From 1d0512957e802acfe7b677b30589a4e3bd26fac8 Mon Sep 17 00:00:00 2001
From: dzwdz
Date: Tue, 14 Sep 2021 20:31:40 +0200
Subject: add support for 4-parameter syscalls

---
 src/init/syscall.s              | 11 +++++++----
 src/init/syscalls.c             | 26 +++++++++++++-------------
 src/kernel/arch/generic.h       |  2 +-
 src/kernel/arch/i386/sysenter.c |  2 +-
 src/kernel/syscalls.c           |  2 +-
 5 files changed, 23 insertions(+), 20 deletions(-)

(limited to 'src')

diff --git a/src/init/syscall.s b/src/init/syscall.s
index 78ce817..bea1452 100644
--- a/src/init/syscall.s
+++ b/src/init/syscall.s
@@ -5,16 +5,19 @@ _syscall:
 	push %ebx // preserve registers
 	push %esi
 	push %edi
+	push %ebp
 
 //  note: i could squeeze out another parameter out of %ebp
-	mov 16(%esp), %eax
-	mov 20(%esp), %ebx
+	mov 20(%esp), %eax
+	mov 24(%esp), %ebx
 	mov %esp, %ecx
 	mov $_syscall_ret, %edx
-	mov 24(%esp), %esi
-	mov 28(%esp), %edi
+	mov 28(%esp), %esi
+	mov 32(%esp), %edi
+	mov 36(%esp), %ebp
 	sysenter
 _syscall_ret:
+	pop %ebp
 	pop %edi
 	pop %esi
 	pop %ebx
diff --git a/src/init/syscalls.c b/src/init/syscalls.c
index 1f80d29..a5d1024 100644
--- a/src/init/syscalls.c
+++ b/src/init/syscalls.c
@@ -2,53 +2,53 @@
 #include <init/types.h>
 #include <shared/syscalls.h>
 
-int _syscall(int, int, int, int);
+int _syscall(int, int, int, int, int);
 
 _Noreturn void _syscall_exit(const char __user *msg, size_t len) {
-	_syscall(_SYSCALL_EXIT, (int)msg, len, 0);
+	_syscall(_SYSCALL_EXIT, (int)msg, len, 0, 0);
 	__builtin_unreachable();
 }
 
 int _syscall_fork(void) {
-	return _syscall(_SYSCALL_FORK, 0, 0, 0);
+	return _syscall(_SYSCALL_FORK, 0, 0, 0, 0);
 }
 
 int _syscall_await(char __user *buf, int len) {
-	return _syscall(_SYSCALL_AWAIT, (int)buf, (int)len, 0);
+	return _syscall(_SYSCALL_AWAIT, (int)buf, (int)len, 0, 0);
 }
 
 handle_t _syscall_open(const char __user *path, int len) {
-	return _syscall(_SYSCALL_OPEN, (int)path, len, 0);
+	return _syscall(_SYSCALL_OPEN, (int)path, len, 0, 0);
 }
 
 int _syscall_mount(handle_t handle, const char __user *path, int len) {
-	return _syscall(_SYSCALL_MOUNT, handle, (int)path, len);
+	return _syscall(_SYSCALL_MOUNT, handle, (int)path, len, 0);
 }
 
 int _syscall_read(handle_t handle, char __user *buf, int len) {
-	return _syscall(_SYSCALL_READ, handle, (int)buf, len);
+	return _syscall(_SYSCALL_READ, handle, (int)buf, len, 0);
 }
 
 int _syscall_write(handle_t handle, const char __user *buf, int len) {
-	return _syscall(_SYSCALL_WRITE, handle, (int)buf, len);
+	return _syscall(_SYSCALL_WRITE, handle, (int)buf, len, 0);
 }
 
 int _syscall_close(handle_t handle) {
-	return _syscall(_SYSCALL_CLOSE, handle, 0, 0);
+	return _syscall(_SYSCALL_CLOSE, handle, 0, 0, 0);
 }
 
 handle_t _syscall_fs_create(handle_t __user *back) {
-	return _syscall(_SYSCALL_FS_CREATE, (int)back, 0, 0);
+	return _syscall(_SYSCALL_FS_CREATE, (int)back, 0, 0, 0);
 }
 
 int _syscall_fs_wait(handle_t back, char __user *buf, int __user *len) {
-	return _syscall(_SYSCALL_FS_WAIT, back, (int)buf, (int)len);
+	return _syscall(_SYSCALL_FS_WAIT, back, (int)buf, (int)len, 0);
 }
 
 int _syscall_fs_respond(char __user *buf, int ret) {
-	return _syscall(_SYSCALL_FS_RESPOND, (int)buf, ret, 0);
+	return _syscall(_SYSCALL_FS_RESPOND, (int)buf, ret, 0, 0);
 }
 
 int _syscall_memflag(void __user *addr, size_t len, int flags) {
-	return _syscall(_SYSCALL_MEMFLAG, (int)addr, len, flags);
+	return _syscall(_SYSCALL_MEMFLAG, (int)addr, len, flags, 0);
 }
diff --git a/src/kernel/arch/generic.h b/src/kernel/arch/generic.h
index 547109f..dd145f7 100644
--- a/src/kernel/arch/generic.h
+++ b/src/kernel/arch/generic.h
@@ -18,7 +18,7 @@ void halt_cpu(void);
 
 // src/arch/i386/sysenter.s
 _Noreturn void sysexit(struct registers);
-int syscall_handler(int, int, int, int);
+int syscall_handler(int, int, int, int, int);
 
 // all of those can allocate memory
 struct pagedir *pagedir_new(void);
diff --git a/src/kernel/arch/i386/sysenter.c b/src/kernel/arch/i386/sysenter.c
index 231aba5..6419439 100644
--- a/src/kernel/arch/i386/sysenter.c
+++ b/src/kernel/arch/i386/sysenter.c
@@ -22,7 +22,7 @@ _Noreturn void sysenter_stage2(void) {
 	regs->eip = (userptr_t) regs->edx;
 
 	val = syscall_handler(regs->eax, regs->ebx,
-	                      regs->esi, regs->edi);
+	                      regs->esi, regs->edi, (uintptr_t)regs->ebp);
 	regs_savereturn(&process_current->regs, val);
 
 	process_switch(process_current); // TODO process_resume
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 6821871..9002628 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -250,7 +250,7 @@ int _syscall_memflag(void __user *addr, size_t len, int flags) {
 	return -1;
 }
 
-int syscall_handler(int num, int a, int b, int c) {
+int syscall_handler(int num, int a, int b, int c, int d) {
 	switch (num) {
 		case _SYSCALL_EXIT:
 			_syscall_exit((userptr_t)a, b);
-- 
cgit v1.2.3