From 8aa38bc8308b514f8ea99f5a5fb12683ef0018c4 Mon Sep 17 00:00:00 2001 From: Clement Dieperink Date: Wed, 27 Aug 2025 14:06:52 +0200 Subject: [PATCH 1/2] refactor syscall into an array and move number into arch depend files --- so3/arch/arm32/include/asm/syscall_number.h | 81 +++++ so3/arch/arm64/include/asm/syscall_number.h | 81 +++++ so3/fs/vfs.c | 40 +-- so3/include/mutex.h | 7 +- so3/include/net.h | 21 +- so3/include/pipe.h | 3 +- so3/include/process.h | 13 +- so3/include/ptrace.h | 3 +- so3/include/signal.h | 7 +- so3/include/syscall.h | 139 ++++---- so3/include/thread.h | 9 +- so3/include/timer.h | 7 +- so3/include/vfs.h | 25 +- so3/ipc/pipe.c | 2 +- so3/ipc/signal.c | 8 +- so3/kernel/delay.c | 2 +- so3/kernel/mutex.c | 4 +- so3/kernel/process.c | 14 +- so3/kernel/ptrace.c | 2 +- so3/kernel/syscalls.c | 341 ++++++-------------- so3/kernel/thread.c | 11 +- so3/kernel/timer.c | 4 +- so3/net/net.c | 20 +- 23 files changed, 443 insertions(+), 401 deletions(-) create mode 100644 so3/arch/arm32/include/asm/syscall_number.h create mode 100644 so3/arch/arm64/include/asm/syscall_number.h diff --git a/so3/arch/arm32/include/asm/syscall_number.h b/so3/arch/arm32/include/asm/syscall_number.h new file mode 100644 index 000000000..7474f8f2e --- /dev/null +++ b/so3/arch/arm32/include/asm/syscall_number.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2025 Clement Dieperink + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef ARCH_ARM32_SYSCALL_NUMBER_H +#define ARCH_ARM32_SYSCALL_NUMBER_H + +/* + * Syscall number definition + */ + +#define SYSCALL_EXIT 1 +#define SYSCALL_EXECVE 2 +#define SYSCALL_WAITPID 3 +#define SYSCALL_READ 4 +#define SYSCALL_WRITE 5 +#define SYSCALL_FORK 7 +#define SYSCALL_PTRACE 8 +#define SYSCALL_READDIR 9 +#define SYSCALL_OPEN 14 +#define SYSCALL_CLOSE 15 +#define SYSCALL_THREAD_CREATE 16 +#define SYSCALL_THREAD_JOIN 17 +#define SYSCALL_THREAD_EXIT 18 +#define SYSCALL_PIPE 19 +#define SYSCALL_IOCTL 20 +#define SYSCALL_FCNTL 21 +#define SYSCALL_DUP 22 +#define SYSCALL_DUP2 23 + +#define SYSCALL_SOCKET 26 +#define SYSCALL_BIND 27 +#define SYSCALL_LISTEN 28 +#define SYSCALL_ACCEPT 29 +#define SYSCALL_CONNECT 30 +#define SYSCALL_RECV 31 +#define SYSCALL_SEND 32 +#define SYSCALL_SENDTO 33 + +#define SYSCALL_STAT 34 +#define SYSCALL_MMAP 35 +#define SYSCALL_GETPID 37 + +#define SYSCALL_GETTIMEOFDAY 38 +#define SYSCALL_SETTIMEOFDAY 39 +#define SYSCALL_CLOCK_GETTIME 40 + +#define SYSCALL_THREAD_YIELD 43 + +#define SYSCALL_SBRK 45 +#define SYSCALL_SIGACTION 46 +#define SYSCALL_KILL 47 +#define SYSCALL_SIGRETURN 48 + +#define SYSCALL_LSEEK 50 + +#define SYSCALL_MUTEX_LOCK 60 +#define SYSCALL_MUTEX_UNLOCK 61 + +#define SYSCALL_NANOSLEEP 70 + +#define SYSCALL_SYSINFO 99 + +#define SYSCALL_SETSOCKOPT 110 +#define SYSCALL_RECVFROM 111 + +#endif /* ARCH_ARM32_SYSCALL_NUMBER_H */ diff --git a/so3/arch/arm64/include/asm/syscall_number.h b/so3/arch/arm64/include/asm/syscall_number.h new file mode 100644 index 000000000..d81a0858a --- /dev/null +++ b/so3/arch/arm64/include/asm/syscall_number.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2025 Clement Dieperink + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef ARCH_ARM64_SYSCALL_NUMBER_H +#define ARCH_ARM64_SYSCALL_NUMBER_H + +/* + * Syscall number definition + */ + +#define SYSCALL_EXIT 1 +#define SYSCALL_EXECVE 2 +#define SYSCALL_WAITPID 3 +#define SYSCALL_READ 4 +#define SYSCALL_WRITE 5 +#define SYSCALL_FORK 7 +#define SYSCALL_PTRACE 8 +#define SYSCALL_READDIR 9 +#define SYSCALL_OPEN 14 +#define SYSCALL_CLOSE 15 +#define SYSCALL_THREAD_CREATE 16 +#define SYSCALL_THREAD_JOIN 17 +#define SYSCALL_THREAD_EXIT 18 +#define SYSCALL_PIPE 19 +#define SYSCALL_IOCTL 20 +#define SYSCALL_FCNTL 21 +#define SYSCALL_DUP 22 +#define SYSCALL_DUP2 23 + +#define SYSCALL_SOCKET 26 +#define SYSCALL_BIND 27 +#define SYSCALL_LISTEN 28 +#define SYSCALL_ACCEPT 29 +#define SYSCALL_CONNECT 30 +#define SYSCALL_RECV 31 +#define SYSCALL_SEND 32 +#define SYSCALL_SENDTO 33 + +#define SYSCALL_STAT 34 +#define SYSCALL_MMAP 35 +#define SYSCALL_GETPID 37 + +#define SYSCALL_GETTIMEOFDAY 38 +#define SYSCALL_SETTIMEOFDAY 39 +#define SYSCALL_CLOCK_GETTIME 40 + +#define SYSCALL_THREAD_YIELD 43 + +#define SYSCALL_SBRK 45 +#define SYSCALL_SIGACTION 46 +#define SYSCALL_KILL 47 +#define SYSCALL_SIGRETURN 48 + +#define SYSCALL_LSEEK 50 + +#define SYSCALL_MUTEX_LOCK 60 +#define SYSCALL_MUTEX_UNLOCK 61 + +#define SYSCALL_NANOSLEEP 70 + +#define SYSCALL_SYSINFO 99 + +#define SYSCALL_SETSOCKOPT 110 +#define SYSCALL_RECVFROM 111 + +#endif /* ARCH_ARM64_SYSCALL_NUMBER_H */ diff --git a/so3/fs/vfs.c b/so3/fs/vfs.c index 28582cf3d..372bb6352 100644 --- a/so3/fs/vfs.c +++ b/so3/fs/vfs.c @@ -379,7 +379,7 @@ int vfs_clone_fd(int *fd_src, int *fd_dst) /**************************** Syscall implementation ****************************/ -int do_read(int fd, void *buffer, int count) +SYSCALL_DEFINE3(read, int, fd, void *, buffer, int, count) { int gfd; int ret; @@ -427,7 +427,7 @@ int do_read(int fd, void *buffer, int count) /** * @brief This function writes a REGULAR FILE/FOLDER. It only support regular file, dirs and pipes */ -int do_write(int fd, const void *buffer, int count) +SYSCALL_DEFINE3(write, int, fd, const void *, buffer, int, count) { int gfd; int ret; @@ -474,7 +474,7 @@ int do_write(int fd, const void *buffer, int count) /** * @brief This function opens a file. Not all file types are supported. */ -int do_open(const char *filename, int flags) +SYSCALL_DEFINE2(open, const char *, filename, int, flags) { int fd, gfd, ret = -1; uint32_t type; @@ -542,7 +542,7 @@ int do_open(const char *filename, int flags) * @brief readdir read a directory entry which will be stored in a struct dirent entry * @param fd This is the file descriptor provided as (DIR *) when doing opendir in the userspace. */ -int do_readdir(int fd, char *buf, int len) +SYSCALL_DEFINE3(readdir, int, fd, char *, buf, int, len) { struct dirent *dirent; int gfd; @@ -588,13 +588,13 @@ int do_readdir(int fd, char *buf, int len) * only when refcount is equal to zero (no more reference on the gfd). * @param fd This is the local fd from the process' table. */ -void do_close(int fd) +SYSCALL_DEFINE1(close, int, fd) { pcb_t *pcb = current()->pcb; int gfd; if ((!pcb) || (fd < 0)) - return; + return 0; mutex_lock(&vfs_lock); @@ -604,12 +604,12 @@ void do_close(int fd) if (gfd < 0) { LOG_DEBUG("Was already freed\n"); mutex_unlock(&vfs_lock); - return; + return 0; } if (!open_fds[gfd]) { mutex_unlock(&vfs_lock); - return; + return 0; } /* Decrement reference counter to keep track of open fds */ @@ -640,13 +640,15 @@ void do_close(int fd) } mutex_unlock(&vfs_lock); + + return 0; } /** * @brief dup2 creates a synonym of oldfd on newfd * */ -int do_dup2(int oldfd, int newfd) +SYSCALL_DEFINE2(dup2, int, oldfd, int, newfd) { if ((newfd < 0) || (newfd > MAX_FDS)) return -EBADF; @@ -680,7 +682,7 @@ int do_dup2(int oldfd, int newfd) * @param File descriptor to copy. * @return A copy of the file descriptor. */ -int do_dup(int oldfd) +SYSCALL_DEFINE1(dup, int, oldfd) { #ifdef CONFIG_PROC_ENV int newfd; @@ -708,7 +710,7 @@ int do_dup(int oldfd) #endif } -int do_stat(const char *path, struct stat *st) +SYSCALL_DEFINE2(stat, const char *, path, struct stat *, st) { int ret; @@ -737,7 +739,7 @@ int do_stat(const char *path, struct stat *st) /** * An mmap() implementation in VFS. */ -void *do_mmap(addr_t start, size_t length, int prot, int fd, off_t offset) +SYSCALL_DEFINE5(mmap, addr_t, start, size_t, length, int, prot, int, fd, off_t, offset) { int gfd; uint32_t page_count; @@ -749,7 +751,7 @@ void *do_mmap(addr_t start, size_t length, int prot, int fd, off_t offset) if (-1 == gfd) { printk("%s: could not get global fd.\n", __func__); set_errno(EBADF); - return MAP_FAILED; + return (long)MAP_FAILED; } mutex_lock(&vfs_lock); @@ -758,7 +760,7 @@ void *do_mmap(addr_t start, size_t length, int prot, int fd, off_t offset) printk("%s: could not get device fops.\n", __func__); mutex_unlock(&vfs_lock); set_errno(EBADF); - return MAP_FAILED; + return (long)MAP_FAILED; } mutex_unlock(&vfs_lock); @@ -772,14 +774,14 @@ void *do_mmap(addr_t start, size_t length, int prot, int fd, off_t offset) if (!fops->mmap) { printk("%s: device doesn't support mmap.\n", __func__); set_errno(EACCES); - return MAP_FAILED; + return (long)MAP_FAILED; } /* Call the mmap fops that will do the actual mapping. */ - return fops->mmap(fd, start, page_count, offset); + return (long)fops->mmap(fd, start, page_count, offset); } -int do_ioctl(int fd, unsigned long cmd, unsigned long args) +SYSCALL_DEFINE3(ioctl, int, fd, unsigned long, cmd, unsigned long, args) { int rc, gfd; mutex_lock(&vfs_lock); @@ -808,7 +810,7 @@ int do_ioctl(int fd, unsigned long cmd, unsigned long args) * Implementation of standard lseek() syscall. It depends on the underlying * device operations. */ -off_t do_lseek(int fd, off_t off, int whence) +SYSCALL_DEFINE3(lseek, int, fd, off_t, off, int, whence) { int rc, gfd; mutex_lock(&vfs_lock); @@ -834,7 +836,7 @@ off_t do_lseek(int fd, off_t off, int whence) /* * Implementation of the fcntl syscall */ -int do_fcntl(int fd, unsigned long cmd, unsigned long args) +SYSCALL_DEFINE3(fcntl, int, fd, unsigned long, cmd, unsigned long, args) { /* Not yet implemented */ diff --git a/so3/include/mutex.h b/so3/include/mutex.h index 268abf169..49f3847c9 100644 --- a/so3/include/mutex.h +++ b/so3/include/mutex.h @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -58,8 +59,8 @@ void mutex_lock(struct mutex *lock); void mutex_unlock(struct mutex *lock); void mutex_init(struct mutex *lock); -int do_mutex_init(void); -int do_mutex_lock(unsigned long number); -int do_mutex_unlock(unsigned long number); +SYSCALL_DECLARE(mutex_init, void); +SYSCALL_DECLARE(mutex_lock, unsigned long number); +SYSCALL_DECLARE(mutex_unlock, unsigned long number); #endif /* MUTEX_H */ diff --git a/so3/include/net.h b/so3/include/net.h index 26019ca82..52a97f27c 100644 --- a/so3/include/net.h +++ b/so3/include/net.h @@ -20,6 +20,7 @@ #define NET_H #include +#include #include @@ -67,15 +68,15 @@ void net_init(void); -int do_socket(int domain, int type, int protocol); -int do_connect(int sockfd, const struct sockaddr *name, socklen_t namelen); -int do_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); -int do_listen(int sockfd, int backlog); -int do_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); -int do_recv(int sockfd, void *mem, size_t len, int flags); -int do_recvfrom(int sockfd, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen); -int do_send(int sockfd, const void *dataptr, size_t size, int flags); -int do_sendto(int sockfd, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen); -int do_setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); +SYSCALL_DECLARE(socket, int domain, int type, int protocol); +SYSCALL_DECLARE(connect, int sockfd, const struct sockaddr *name, socklen_t namelen); +SYSCALL_DECLARE(bind, int sockfd, const struct sockaddr *addr, socklen_t addrlen); +SYSCALL_DECLARE(listen, int sockfd, int backlog); +SYSCALL_DECLARE(accept, int sockfd, struct sockaddr *addr, socklen_t *addrlen); +SYSCALL_DECLARE(recv, int sockfd, void *mem, size_t len, int flags); +SYSCALL_DECLARE(recvfrom, int sockfd, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen); +SYSCALL_DECLARE(send, int sockfd, const void *dataptr, size_t size, int flags); +SYSCALL_DECLARE(sendto, int sockfd, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen); +SYSCALL_DECLARE(setsockopt, int sockfd, int level, int optname, const void *optval, socklen_t optlen); #endif /* NET_H */ diff --git a/so3/include/pipe.h b/so3/include/pipe.h index 675f797af..961f0b4c9 100644 --- a/so3/include/pipe.h +++ b/so3/include/pipe.h @@ -22,6 +22,7 @@ #include #include #include +#include #define PIPE_READER 0 #define PIPE_WRITER 0 @@ -52,6 +53,6 @@ struct pipe_desc { }; typedef struct pipe_desc pipe_desc_t; -int do_pipe(int pipefd[2]); +SYSCALL_DECLARE(pipe, int *pipefd); #endif /* PIPE_H */ diff --git a/so3/include/process.h b/so3/include/process.h index 586d95307..1623daa1b 100644 --- a/so3/include/process.h +++ b/so3/include/process.h @@ -30,6 +30,7 @@ #include #include #include +#include #define PROC_MAX 64 #define PROC_MAX_THREADS CONFIG_MAX_THREADS @@ -133,12 +134,12 @@ void add_page_to_proc(pcb_t *pcb, page_t *page); void create_root_process(void); -uint32_t do_getpid(void); +SYSCALL_DECLARE(getpid, void); -int do_execve(const char *filename, char **argv, char **envp); -int do_fork(void); -void do_exit(int exit_status); -int do_waitpid(int pid, uint32_t *wstatus, uint32_t options); +SYSCALL_DECLARE(execve, const char *filename, char **argv, char **envp); +SYSCALL_DECLARE(fork, void); +SYSCALL_DECLARE(exit, int exit_status); +SYSCALL_DECLARE(waitpid, int pid, uint32_t *wstatus, uint32_t options); pcb_t *find_proc_by_pid(uint32_t pid); @@ -149,6 +150,6 @@ void dump_proc(void); extern int __exec(const char *file); extern int __write(int fd, char *buffer, int count); -int do_sbrk(int increment); +SYSCALL_DECLARE(sbrk, int increment); #endif /* PROCESS_H */ diff --git a/so3/include/ptrace.h b/so3/include/ptrace.h index f3e083c85..e2b828721 100644 --- a/so3/include/ptrace.h +++ b/so3/include/ptrace.h @@ -20,6 +20,7 @@ #ifndef _SYS_PTRACE_H #define _SYS_PTRACE_H +#include #include /* Type of the REQUEST argument to `ptrace.' */ @@ -207,7 +208,7 @@ struct ptrace_peeksiginfo_args { int32_t nr; }; -int do_ptrace(enum __ptrace_request request, uint32_t pid, void *addr, void *data); +SYSCALL_DECLARE(ptrace, enum __ptrace_request request, uint32_t pid, void *addr, void *data); struct pcb; struct user; diff --git a/so3/include/signal.h b/so3/include/signal.h index 450b09ee3..b4f8156a8 100644 --- a/so3/include/signal.h +++ b/so3/include/signal.h @@ -20,6 +20,7 @@ #ifndef SIGNAL_H #define SIGNAL_H +#include #include #include @@ -93,8 +94,8 @@ typedef struct __sigaction { sigaction_t *sa; } __sigaction_t; -int do_sigaction(int signum, const sigaction_t *action, sigaction_t *old_action); -int do_kill(int pid, int sig); -void do_sigreturn(void); +SYSCALL_DECLARE(sigaction, int signum, const sigaction_t *action, sigaction_t *old_action); +SYSCALL_DECLARE(kill, int pid, int sig); +SYSCALL_DECLARE(sigreturn, void); #endif /* SIGNAL_H */ diff --git a/so3/include/syscall.h b/so3/include/syscall.h index 7445bd819..055ae0d24 100644 --- a/so3/include/syscall.h +++ b/so3/include/syscall.h @@ -27,77 +27,100 @@ #define SYSINFO_PRINTK 3 #define SYSINFO_DUMP_PROC 4 -/* - * Syscall number definition - */ - -#define SYSCALL_EXIT 1 -#define SYSCALL_EXECVE 2 -#define SYSCALL_WAITPID 3 -#define SYSCALL_READ 4 -#define SYSCALL_WRITE 5 -#define SYSCALL_FORK 7 -#define SYSCALL_PTRACE 8 -#define SYSCALL_READDIR 9 -#define SYSCALL_OPEN 14 -#define SYSCALL_CLOSE 15 -#define SYSCALL_THREAD_CREATE 16 -#define SYSCALL_THREAD_JOIN 17 -#define SYSCALL_THREAD_EXIT 18 -#define SYSCALL_PIPE 19 -#define SYSCALL_IOCTL 20 -#define SYSCALL_FCNTL 21 -#define SYSCALL_DUP 22 -#define SYSCALL_DUP2 23 - -#define SYSCALL_SOCKET 26 -#define SYSCALL_BIND 27 -#define SYSCALL_LISTEN 28 -#define SYSCALL_ACCEPT 29 -#define SYSCALL_CONNECT 30 -#define SYSCALL_RECV 31 -#define SYSCALL_SEND 32 -#define SYSCALL_SENDTO 33 - -#define SYSCALL_STAT 34 -#define SYSCALL_MMAP 35 -#define SYSCALL_GETPID 37 - -#define SYSCALL_GETTIMEOFDAY 38 -#define SYSCALL_SETTIMEOFDAY 39 -#define SYSCALL_CLOCK_GETTIME 40 - -#define SYSCALL_THREAD_YIELD 43 - -#define SYSCALL_SBRK 45 -#define SYSCALL_SIGACTION 46 -#define SYSCALL_KILL 47 -#define SYSCALL_SIGRETURN 48 - -#define SYSCALL_LSEEK 50 - -#define SYSCALL_MUTEX_LOCK 60 -#define SYSCALL_MUTEX_UNLOCK 61 - -#define SYSCALL_NANOSLEEP 70 - -#define SYSCALL_SYSINFO 99 - -#define SYSCALL_SETSOCKOPT 110 -#define SYSCALL_RECVFROM 111 +#include #ifndef __ASSEMBLY__ #include #include +#define NR_SYSCALLS 468 + +/** + * Map arguments set (type, name) into a comma separated list + * e.g. function arguments + * + * @param x Number of arguments to map + * @param m Macro mapping type and name correctly + * @param t Type of the function arguments + * @param n name of the function arguments + */ +#define __MAP1(m,t,n) m(t,n) +#define __MAP2(m,t,n,...) m(t,n), __MAP1(m,__VA_ARGS__) +#define __MAP3(m,t,n,...) m(t,n), __MAP2(m,__VA_ARGS__) +#define __MAP4(m,t,n,...) m(t,n), __MAP3(m,__VA_ARGS__) +#define __MAP5(m,t,n,...) m(t,n), __MAP4(m,__VA_ARGS__) +#define __MAP6(m,t,n,...) m(t,n), __MAP5(m,__VA_ARGS__) +#define __MAP(x,m,...) __MAP##x(m,__VA_ARGS__) + +/** Macros to map type and name with __MAP */ +#define __M_DECL(t,n) t n +#define __M_LONG(t,n) long n +#define __M_ARGS(t,n) n + +/** + * Map syscall arguments by casting them for function call. + * + * @param x Number of arguments to map + * @param args Arguments array to use + * @param m Macro mapping type and name correctly + * @param t Type of the function arguments + * @param n name of the function arguments, not use but allow + * to use same __VA_ARGS__ as in __MAP() + */ +#define __MAP_ARGS1(x,args,t,n) (t)args[x-1] +#define __MAP_ARGS2(x,args,t,n,...) (t)args[x-2], __MAP_ARGS1(x,args,__VA_ARGS__) +#define __MAP_ARGS3(x,args,t,n,...) (t)args[x-3], __MAP_ARGS2(x,args,__VA_ARGS__) +#define __MAP_ARGS4(x,args,t,n,...) (t)args[x-4], __MAP_ARGS3(x,args,__VA_ARGS__) +#define __MAP_ARGS5(x,args,t,n,...) (t)args[x-5], __MAP_ARGS4(x,args,__VA_ARGS__) +#define __MAP_ARGS6(x,args,t,n,...) (t)args[x-6], __MAP_ARGS5(x,args,__VA_ARGS__) +#define __MAP_ARGS(x,args,...) __MAP_ARGS##x((x),(args),__VA_ARGS__) + +/** + * Syscall functions declaration and definitions helper. + * + * Two functions are added for each syscall. + * + * __sys_SYSCALL_NAME taking syscall_args_t as arguments allowing for + * a common interface between all syscall to put them in an array. + * + * do_SYSCALL_NAME actual function with the syscall implementation with + * arguments define like a normal function. That function is automatically + * called by __sys_SYCALL_NAME with the correct argument number and cast. + */ +#define SYSCALL_DECLARE(name,...) \ + long __sys_##name(syscall_args_t *args); \ + inline long do_##name(__VA_ARGS__); + +#define SYSCALL_DEFINE0(name) \ + long __sys_##name(syscall_args_t *unused) { return do_##name(); } \ + inline long do_##name(void) +#define SYSCALL_DEFINE1(...) __SYSCALL_DEFINEx(1,__VA_ARGS__) +#define SYSCALL_DEFINE2(...) __SYSCALL_DEFINEx(2,__VA_ARGS__) +#define SYSCALL_DEFINE3(...) __SYSCALL_DEFINEx(3,__VA_ARGS__) +#define SYSCALL_DEFINE4(...) __SYSCALL_DEFINEx(4,__VA_ARGS__) +#define SYSCALL_DEFINE5(...) __SYSCALL_DEFINEx(5,__VA_ARGS__) +#define SYSCALL_DEFINE6(...) __SYSCALL_DEFINEx(6,__VA_ARGS__) + +#define __SYSCALL_DEFINEx(x,name,...) \ + long __sys_##name(syscall_args_t *args) \ + { \ + return do_##name(__MAP_ARGS(x,args->args,__VA_ARGS__)); \ + } \ + inline long do_##name(__MAP(x,__M_DECL,__VA_ARGS__)) + typedef struct { unsigned long args[6]; } syscall_args_t; +typedef long (*syscall_fn_t)(syscall_args_t *); + long syscall_handle(syscall_args_t *); void set_errno(uint32_t val); + +SYSCALL_DECLARE(sysinfo, unsigned long info_number, char *text); + #endif /* __ASSEMBLY__ */ #endif /* ASM_ARM_SYSCALL_H */ diff --git a/so3/include/thread.h b/so3/include/thread.h index 873a74c98..32721149e 100644 --- a/so3/include/thread.h +++ b/so3/include/thread.h @@ -28,6 +28,7 @@ #include #include +#include typedef enum { THREAD_STATE_NEW, @@ -98,9 +99,9 @@ addr_t get_user_stack_top(pcb_t *pcb, uint32_t slotID); void threads_init(void); -int do_thread_create(uint32_t *pthread_id, addr_t attr_p, addr_t thread_fn, addr_t arg_p); -int do_thread_join(uint32_t pthread_id, int **value_p); -void do_thread_exit(int *exit_status); +SYSCALL_DECLARE(thread_create, uint32_t *pthread_id, addr_t attr_p, addr_t thread_fn, addr_t arg_p); +SYSCALL_DECLARE(thread_join, uint32_t pthread_id, int **value_p); +SYSCALL_DECLARE(thread_exit, int *exit_status); tcb_t *kernel_thread(th_fn_t start_routine, const char *name, void *arg, uint32_t prio); tcb_t *user_thread(th_fn_t start_routine, const char *name, void *arg, pcb_t *pcb); @@ -108,7 +109,7 @@ tcb_t *user_thread(th_fn_t start_routine, const char *name, void *arg, pcb_t *pc int *thread_join(tcb_t *tcb); void thread_exit(int *exit_status); void clean_thread(tcb_t *tcb); -void do_thread_yield(void); +SYSCALL_DECLARE(thread_yield, void); void *thread_idle(void *dummy); diff --git a/so3/include/timer.h b/so3/include/timer.h index e9781f1b7..bb125c666 100644 --- a/so3/include/timer.h +++ b/so3/include/timer.h @@ -23,6 +23,7 @@ #include #include +#include #define NSECS 1000000000ull @@ -125,10 +126,10 @@ void clocksource_timer_reset(void); void clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 maxsec); -int do_nanosleep(const struct timespec *req, struct timespec *rem); +SYSCALL_DECLARE(nanosleep, const struct timespec *req, struct timespec *rem); -int do_get_time_of_day(struct timespec *tv); -int do_get_clock_time(int clk_id, struct timespec *ts); +SYSCALL_DECLARE(gettimeofday, struct timespec *tv); +SYSCALL_DECLARE(clock_gettime, int clk_id, struct timespec *ts); #ifdef CONFIG_AVZ diff --git a/so3/include/vfs.h b/so3/include/vfs.h index 9a21a7573..0641bca42 100644 --- a/so3/include/vfs.h +++ b/so3/include/vfs.h @@ -99,6 +99,7 @@ #include #include #include +#include #include @@ -149,18 +150,18 @@ typedef enum { /* Syscall accessible from userspace */ -int do_open(const char *filename, int flags); -int do_read(int fd, void *buffer, int count); -int do_write(int fd, const void *buffer, int count); -int do_readdir(int fd, char *buf, int len); -void do_close(int fd); -int do_dup(int oldfd); -int do_dup2(int oldfd, int newfd); -int do_stat(const char *path, struct stat *st); -void *do_mmap(addr_t start, size_t length, int prot, int fd, off_t offset); -int do_ioctl(int fd, unsigned long cmd, unsigned long args); -int do_fcntl(int fd, unsigned long cmd, unsigned long args); -off_t do_lseek(int fd, off_t off, int whence); +SYSCALL_DECLARE(open, const char *filename, int flags); +SYSCALL_DECLARE(read, int fd, void *buffer, int count); +SYSCALL_DECLARE(write, int fd, const void *buffer, int count); +SYSCALL_DECLARE(readdir, int fd, char *buf, int len); +SYSCALL_DECLARE(close, int fd); +SYSCALL_DECLARE(dup, int oldfd); +SYSCALL_DECLARE(dup2, int oldfd, int newfd); +SYSCALL_DECLARE(stat, const char *path, struct stat *st); +SYSCALL_DECLARE(mmap, addr_t start, size_t length, int prot, int fd, off_t offset); +SYSCALL_DECLARE(ioctl, int fd, unsigned long cmd, unsigned long args); +SYSCALL_DECLARE(fcntl, int fd, unsigned long cmd, unsigned long args); +SYSCALL_DECLARE(lseek, int fd, off_t off, int whence); /* VFS common interface */ diff --git a/so3/ipc/pipe.c b/so3/ipc/pipe.c index 70ca0805c..fb91c227f 100644 --- a/so3/ipc/pipe.c +++ b/so3/ipc/pipe.c @@ -259,7 +259,7 @@ struct file_operations pipe_fops = { .read = pipe_read, .write = pipe_write, .cl * @return an array of two file descriptors (in/out) to access the pipe. */ -int do_pipe(int pipefd[2]) +SYSCALL_DEFINE1(pipe, int *, pipefd) { /* Allocated two file descriptor */ pipe_desc_t *pd = (struct pipe_desc *) memalign(sizeof(pipe_desc_t), 2); diff --git a/so3/ipc/signal.c b/so3/ipc/signal.c index aa3cd12e5..9215d09b7 100644 --- a/so3/ipc/signal.c +++ b/so3/ipc/signal.c @@ -26,7 +26,7 @@ #include -void do_sigreturn(void) +SYSCALL_DEFINE0(sigreturn) { /* Nothing at the moment ... */ @@ -39,6 +39,8 @@ void do_sigreturn(void) * Cleaning the stack frame used for signal handling will be carried out * during along the return path to the user space. */ + + return 0; } /** @@ -100,7 +102,7 @@ void __mem(int a, char *adr, int log) { } #endif /* 0 */ -int do_sigaction(int signum, const sigaction_t *action, sigaction_t *old_action) +SYSCALL_DEFINE3(sigaction, int, signum, const sigaction_t *, action, sigaction_t *, old_action) { if (signum < 0 || signum >= _NSIG) { LOG_ERROR("signum not valid!\n"); @@ -121,7 +123,7 @@ int do_sigaction(int signum, const sigaction_t *action, sigaction_t *old_action) return 0; } -int do_kill(int pid, int sig) +SYSCALL_DEFINE2(kill, int, pid, int, sig) { pcb_t *proc; unsigned long flags; diff --git a/so3/kernel/delay.c b/so3/kernel/delay.c index 243bc1778..59099520c 100644 --- a/so3/kernel/delay.c +++ b/so3/kernel/delay.c @@ -116,7 +116,7 @@ void sleep(u64 ns) __sleep(ns); } -int do_nanosleep(const struct timespec *req, struct timespec *rem) +SYSCALL_DEFINE2(nanosleep, const struct timespec *, req, struct timespec *, rem) { if (req->tv_nsec != 0) __sleep(req->tv_nsec); diff --git a/so3/kernel/mutex.c b/so3/kernel/mutex.c index bab584a59..e845f863b 100644 --- a/so3/kernel/mutex.c +++ b/so3/kernel/mutex.c @@ -149,7 +149,7 @@ void mutex_unlock(struct mutex *lock) /* * The following syscall implementation are a first attempt, mainly used for debugging kernel mutexes. */ -int do_mutex_lock(unsigned long number) +SYSCALL_DEFINE1(mutex_lock, unsigned long, number) { if (number >= N_MUTEX) { set_errno(EINVAL); @@ -159,7 +159,7 @@ int do_mutex_lock(unsigned long number) return 0; } -int do_mutex_unlock(unsigned long number) +SYSCALL_DEFINE1(mutex_unlock, unsigned long, number) { if (number >= N_MUTEX) { set_errno(EINVAL); diff --git a/so3/kernel/process.c b/so3/kernel/process.c index e32d5f853..ba2fd488e 100644 --- a/so3/kernel/process.c +++ b/so3/kernel/process.c @@ -692,7 +692,7 @@ void load_process(elf_img_info_t *elf_img_info) flush_dcache_all(); } -int do_execve(const char *filename, char **argv, char **envp) +SYSCALL_DEFINE3(execve, const char *, filename, char **, argv, char **, envp) { elf_img_info_t elf_img_info; pcb_t *pcb; @@ -827,7 +827,7 @@ pcb_t *duplicate_process(pcb_t *parent) /* * For a new process from the current running process. */ -int do_fork(void) +SYSCALL_DEFINE0(fork) { pcb_t *newp, *parent; unsigned long flags; @@ -895,7 +895,7 @@ int do_fork(void) * All allocated resources should be released except its PCB which still * contains the exit code. */ -void do_exit(int exit_status) +SYSCALL_DEFINE1(exit, int, exit_status) { pcb_t *pcb; unsigned i; @@ -955,12 +955,14 @@ void do_exit(int exit_status) */ thread_exit(NULL); + + return 0; } /* * Returns the PID of the current process */ -uint32_t do_getpid(void) +SYSCALL_DEFINE0(getpid) { return current()->pcb->pid; } @@ -975,7 +977,7 @@ uint32_t do_getpid(void) * - Clean the PCB and page tables * - Return the pid if successful operation */ -int do_waitpid(int pid, uint32_t *wstatus, uint32_t options) +SYSCALL_DEFINE3(waitpid, int, pid, uint32_t *, wstatus, uint32_t, options) { pcb_t *child; unsigned long flags; @@ -1088,7 +1090,7 @@ int do_waitpid(int pid, uint32_t *wstatus, uint32_t options) * @return This function will the position of the end of the heap / program *break before increment */ -int do_sbrk(int increment) +SYSCALL_DEFINE1(sbrk, int, increment) { pcb_t *pcb = current()->pcb; int ret_pointer; diff --git a/so3/kernel/ptrace.c b/so3/kernel/ptrace.c index 176f9f8c1..ec5afc0b9 100644 --- a/so3/kernel/ptrace.c +++ b/so3/kernel/ptrace.c @@ -64,7 +64,7 @@ void __check_ptrace_syscall(void) /* * Implementation of ptrace syscall */ -int do_ptrace(enum __ptrace_request request, uint32_t pid, void *addr, void *data) +SYSCALL_DEFINE4(ptrace, enum __ptrace_request, request, uint32_t, pid, void *, addr, void *, data) { pcb_t *pcb; diff --git a/so3/kernel/syscalls.c b/so3/kernel/syscalls.c index 968a53abd..596db0105 100644 --- a/so3/kernel/syscalls.c +++ b/so3/kernel/syscalls.c @@ -37,6 +37,64 @@ extern uint32_t __get_syscall_stack_arg(uint32_t nr); extern void test_malloc(int test_no); +static const syscall_fn_t syscall_table[NR_SYSCALLS] = { + [0 ... NR_SYSCALLS - 1] = NULL, + +#ifdef CONFIG_MMU + [SYSCALL_GETPID] = __sys_getpid, + [SYSCALL_GETTIMEOFDAY] = __sys_gettimeofday, + [SYSCALL_CLOCK_GETTIME] = __sys_clock_gettime, + [SYSCALL_EXIT] = __sys_exit, + [SYSCALL_EXECVE] = __sys_execve, + [SYSCALL_FORK] = __sys_fork, + [SYSCALL_WAITPID] = __sys_waitpid, + [SYSCALL_PTRACE] = __sys_ptrace, +#endif + [SYSCALL_READ] = __sys_read, + [SYSCALL_WRITE] = __sys_write, + [SYSCALL_OPEN] = __sys_open, + [SYSCALL_CLOSE] = __sys_close, + [SYSCALL_THREAD_CREATE] = __sys_thread_create, + [SYSCALL_THREAD_JOIN] = __sys_thread_join, + [SYSCALL_THREAD_EXIT] = __sys_thread_exit, + [SYSCALL_THREAD_YIELD] = __sys_thread_yield, + [SYSCALL_READDIR] = __sys_readdir, + [SYSCALL_IOCTL] = __sys_ioctl, + [SYSCALL_FCNTL] = __sys_fcntl, + [SYSCALL_LSEEK] = __sys_lseek, +#ifdef CONFIG_IPC_PIPE + [SYSCALL_PIPE] = __sys_pipe, +#endif + [SYSCALL_DUP] = __sys_dup, + [SYSCALL_DUP2] = __sys_dup2, + [SYSCALL_STAT] = __sys_stat, + [SYSCALL_MMAP] = __sys_mmap, + [SYSCALL_NANOSLEEP] = __sys_nanosleep, +#ifdef CONFIG_PROC_ENV + [SYSCALL_SBRK] = __sys_sbrk, +#endif + [SYSCALL_MUTEX_LOCK] = __sys_mutex_lock, + [SYSCALL_MUTEX_UNLOCK] = __sys_mutex_unlock, +#ifdef CONFIG_IPC_SIGNAL + [SYSCALL_SIGACTION] = __sys_sigaction, + [SYSCALL_KILL] = __sys_kill, + [SYSCALL_SIGRETURN] = __sys_sigreturn, +#endif +#ifdef CONFIG_NET + [SYSCALL_SOCKET] = __sys_socket, + [SYSCALL_BIND] = __sys_bind, + [SYSCALL_LISTEN] = __sys_listen, + [SYSCALL_ACCEPT] = __sys_accept, + [SYSCALL_CONNECT] = __sys_connect, + [SYSCALL_RECV] = __sys_recv, + [SYSCALL_SEND] = __sys_send, + [SYSCALL_SENDTO] = __sys_sendto, + [SYSCALL_SETSOCKOPT] = __sys_setsockopt, + [SYSCALL_RECVFROM] = __sys_recvfrom, +#endif + [SYSCALL_SYSINFO] = __sys_sysinfo, +}; + /* * Set the (user space) virtual address of the global variable which is defined in the libc. * is used to keep a error number in case of syscall execution failure. @@ -60,274 +118,55 @@ void set_errno(uint32_t val) *errno_addr = val; } -/* - * Process syscalls according to the syscall number passed in r7 on ARM and x8 on ARM64. - * According to SO3 ABI, the syscall arguments are passed in r0-r5 on ARM and x0-x5 on ARM64. - */ - -long syscall_handle(syscall_args_t *syscall_args) +SYSCALL_DEFINE2(sysinfo, unsigned long, info_number, char *, text) { - long result = -1; - uint32_t syscall_no, *__errno_addr; - - /* Get addtional args of the syscall according to the ARM & SO3 ABI */ - __get_syscall_args_ext(&syscall_no, &__errno_addr); - - set_errno_addr(__errno_addr); - - switch (syscall_no) { -#ifdef CONFIG_MMU - case SYSCALL_GETPID: - result = do_getpid(); + switch (info_number) { + case SYSINFO_DUMP_HEAP: + dump_heap("Heap info asked from user.\n"); break; - case SYSCALL_GETTIMEOFDAY: - /* a->args[1] contains a pointer to the timezone structure. */ - /* Currently, this is not supported yet. */ - - result = do_get_time_of_day((struct timespec *) syscall_args->args[0]); - break; - - case SYSCALL_CLOCK_GETTIME: - - result = do_get_clock_time(syscall_args->args[0], (struct timespec *) syscall_args->args[1]); - break; - - case SYSCALL_SETTIMEOFDAY: - - printk("## settimeofday not yet supported by so3\n"); - - set_errno(-ENOSYS); - result = -1; - break; - - case SYSCALL_EXIT: - do_exit(syscall_args->args[0]); - break; - - case SYSCALL_EXECVE: - result = do_execve((const char *) syscall_args->args[0], (char **) syscall_args->args[1], - (char **) syscall_args->args[2]); - break; - - case SYSCALL_FORK: - result = do_fork(); - break; - - case SYSCALL_WAITPID: - result = do_waitpid(syscall_args->args[0], (uint32_t *) syscall_args->args[1], syscall_args->args[2]); - break; -#endif /* CONFIG_MMU */ - - case SYSCALL_READ: - result = do_read(syscall_args->args[0], (void *) syscall_args->args[1], syscall_args->args[2]); - break; - - case SYSCALL_WRITE: - result = do_write(syscall_args->args[0], (void *) syscall_args->args[1], syscall_args->args[2]); - break; - - case SYSCALL_OPEN: - result = do_open((const char *) syscall_args->args[0], syscall_args->args[1]); - break; - - case SYSCALL_CLOSE: - do_close((int) syscall_args->args[0]); - result = 0; - break; - - case SYSCALL_THREAD_CREATE: - result = do_thread_create((uint32_t *) syscall_args->args[0], syscall_args->args[1], syscall_args->args[2], - syscall_args->args[3]); - break; - - case SYSCALL_THREAD_JOIN: - result = do_thread_join(syscall_args->args[0], (int **) syscall_args->args[1]); - break; - - case SYSCALL_THREAD_EXIT: - do_thread_exit((int *) syscall_args->args[0]); - result = 0; - break; - - case SYSCALL_THREAD_YIELD: - do_thread_yield(); - result = 0; - break; - - case SYSCALL_READDIR: - result = do_readdir((int) syscall_args->args[0], (char *) syscall_args->args[1], syscall_args->args[2]); - break; - - case SYSCALL_IOCTL: - result = do_ioctl((int) syscall_args->args[0], (unsigned long) syscall_args->args[1], - (unsigned long) syscall_args->args[2]); - break; - - case SYSCALL_FCNTL: - result = do_fcntl((int) syscall_args->args[0], (int) syscall_args->args[1], - (unsigned long) syscall_args->args[2]); - break; - - case SYSCALL_LSEEK: - result = do_lseek((int) syscall_args->args[0], (off_t) syscall_args->args[1], (int) syscall_args->args[2]); - break; - -#ifdef CONFIG_IPC_PIPE - case SYSCALL_PIPE: - result = do_pipe((int *) syscall_args->args[0]); - break; -#endif /* CONFIG_IPC_PIPE */ - - case SYSCALL_DUP: - result = do_dup((int) syscall_args->args[0]); - break; - - case SYSCALL_DUP2: - result = do_dup2((int) syscall_args->args[0], (int) syscall_args->args[1]); - break; - - case SYSCALL_STAT: - result = do_stat((char *) syscall_args->args[0], (struct stat *) syscall_args->args[1]); - break; - - case SYSCALL_MMAP: - result = (long) do_mmap((addr_t) syscall_args->args[0], (size_t) syscall_args->args[1], - (int) syscall_args->args[2], (int) syscall_args->args[3], - (off_t) syscall_args->args[4]); - break; - - case SYSCALL_NANOSLEEP: - result = do_nanosleep((const struct timespec *) syscall_args->args[0], - (struct timespec *) syscall_args->args[1]); - break; - -#ifdef CONFIG_PROC_ENV - case SYSCALL_SBRK: - result = do_sbrk((unsigned long) syscall_args->args[0]); - break; - -#endif /* CONFIG_PROC_ENV */ - - /* This is a first attempt of mutex syscall implementation. - * Mainly used for debugging purposes (kernel mutex validation) at the moment ... */ - - case SYSCALL_MUTEX_LOCK: - result = do_mutex_lock(syscall_args->args[0]); - break; - - case SYSCALL_MUTEX_UNLOCK: - result = do_mutex_unlock(syscall_args->args[0]); + case SYSINFO_DUMP_SCHED: + dump_sched(); break; #ifdef CONFIG_MMU - case SYSCALL_PTRACE: - result = do_ptrace((enum __ptrace_request) syscall_args->args[0], (uint32_t) syscall_args->args[1], - (void *) syscall_args->args[2], (void *) syscall_args->args[3]); + case SYSINFO_DUMP_PROC: + dump_proc(); break; #endif -#ifdef CONFIG_IPC_SIGNAL - case SYSCALL_SIGACTION: - result = do_sigaction((int) syscall_args->args[0], (sigaction_t *) syscall_args->args[1], - (sigaction_t *) syscall_args->args[2]); - break; - - case SYSCALL_KILL: - result = do_kill((int) syscall_args->args[0], (int) syscall_args->args[1]); - break; - - case SYSCALL_SIGRETURN: - do_sigreturn(); - break; - -#endif /* CONFIG_IPC_SIGNAL */ - -#ifdef CONFIG_NET - case SYSCALL_SOCKET: - result = do_socket((int) syscall_args->args[0], (int) syscall_args->args[1], (int) syscall_args->args[2]); - break; - - case SYSCALL_BIND: - result = do_bind((int) syscall_args->args[0], (const struct sockaddr *) syscall_args->args[1], - (socklen_t) syscall_args->args[2]); - break; - - case SYSCALL_LISTEN: - result = do_listen((int) syscall_args->args[0], (int) syscall_args->args[1]); - break; - - case SYSCALL_ACCEPT: - result = do_accept((int) syscall_args->args[0], (struct sockaddr *) syscall_args->args[1], - (socklen_t *) syscall_args->args[2]); - break; - - case SYSCALL_CONNECT: - result = do_connect((int) syscall_args->args[0], (const struct sockaddr *) syscall_args->args[1], - (socklen_t) syscall_args->args[2]); - break; - - case SYSCALL_RECV: - result = do_recv((int) syscall_args->args[0], (void *) syscall_args->args[1], (size_t) syscall_args->args[2], - (int) syscall_args->args[3]); - break; - - case SYSCALL_SEND: - result = do_send((int) syscall_args->args[0], (const void *) syscall_args->args[1], - (size_t) syscall_args->args[2], (int) syscall_args->args[3]); - break; - - case SYSCALL_SENDTO: - result = do_sendto((int) syscall_args->args[0], (const void *) syscall_args->args[1], - (size_t) syscall_args->args[2], (int) syscall_args->args[3], - (const struct sockaddr *) syscall_args->args[4], (socklen_t) syscall_args->args[5]); - break; - - case SYSCALL_SETSOCKOPT: - result = do_setsockopt((int) syscall_args->args[0], (int) syscall_args->args[1], (int) syscall_args->args[2], - (const void *) syscall_args->args[3], (socklen_t) syscall_args->args[4]); +#ifdef CONFIG_APP_TEST_MALLOC + case SYSINFO_TEST_MALLOC: + test_malloc(a->args[1]); break; - - case SYSCALL_RECVFROM: - result = do_recvfrom((int) syscall_args->args[0], (void *) syscall_args->args[1], - (size_t) syscall_args->args[2], (int) syscall_args->args[3], - (struct sockaddr *) syscall_args->args[4], (socklen_t *) syscall_args->args[5]); +#endif + case SYSINFO_PRINTK: + printk("%s", (char *) text); break; + } + return 0; +} -#endif /* CONFIG_NET */ - - /* Sysinfo syscalls */ - case SYSCALL_SYSINFO: - switch (syscall_args->args[0]) { - case SYSINFO_DUMP_HEAP: - dump_heap("Heap info asked from user.\n"); - break; +/* + * Process syscalls according to the syscall number passed in r7 on ARM and x8 on ARM64. + * According to SO3 ABI, the syscall arguments are passed in r0-r5 on ARM and x0-x5 on ARM64. + */ - case SYSINFO_DUMP_SCHED: - dump_sched(); - break; +long syscall_handle(syscall_args_t *syscall_args) +{ + long result = -1; + uint32_t syscall_no, *__errno_addr; -#ifdef CONFIG_MMU - case SYSINFO_DUMP_PROC: - dump_proc(); - break; -#endif + /* Get addtional args of the syscall according to the ARM & SO3 ABI */ + __get_syscall_args_ext(&syscall_no, &__errno_addr); -#ifdef CONFIG_APP_TEST_MALLOC - case SYSINFO_TEST_MALLOC: - test_malloc(a->args[1]); - break; -#endif - case SYSINFO_PRINTK: - printk("%s", (char *) syscall_args->args[1]); - break; - } - result = 0; - break; + set_errno_addr(__errno_addr); - default: + if ((syscall_no >= NR_SYSCALLS) || (syscall_table[syscall_no] == NULL)) { printk("%s: unhandled syscall: %d\n", __func__, syscall_no); - break; + return -ENOSYS; + } else { + return syscall_table[syscall_no](syscall_args); } #warning do_softirq? diff --git a/so3/kernel/thread.c b/so3/kernel/thread.c index c53af6e9c..50e6fea3f 100644 --- a/so3/kernel/thread.c +++ b/so3/kernel/thread.c @@ -366,9 +366,10 @@ void *thread_idle(void *dummy) /* * Yield to another thread, i.e. simply invoke a call to schedule() */ -void do_thread_yield(void) +SYSCALL_DEFINE0(thread_yield) { schedule(); + return 0; } void set_thread_registers(tcb_t *thread, cpu_regs_t *regs) @@ -607,7 +608,7 @@ int *thread_join(tcb_t *tcb) * The function returns 0 if successful. */ -int do_thread_create(uint32_t *pthread_id, addr_t attr_p, addr_t thread_fn, addr_t arg_p) +SYSCALL_DEFINE4(thread_create, uint32_t *, pthread_id, addr_t, attr_p, addr_t, thread_fn, addr_t, arg_p) { unsigned long flags; tcb_t *tcb; @@ -643,7 +644,7 @@ int do_thread_create(uint32_t *pthread_id, addr_t attr_p, addr_t thread_fn, addr /* * Join an existing thread */ -int do_thread_join(uint32_t pthread_id, int **value_p) +SYSCALL_DEFINE2(thread_join, uint32_t, pthread_id, int **, value_p) { tcb_t *tcb; int *ret; @@ -671,13 +672,15 @@ int do_thread_join(uint32_t pthread_id, int **value_p) /* * do_thread_exit() is called when pthread_exit() is executed. */ -void do_thread_exit(int *exit_status) +SYSCALL_DEFINE1(thread_exit, int *, exit_status) { /* Unallocate the user space stack slot if it is not the main thread */ if (current() != current()->pcb->main_thread) free_user_stack_slot(current()->pcb, current()->pcb_stack_slotID); thread_exit(exit_status); + + return 0; } void threads_init(void) diff --git a/so3/kernel/timer.c b/so3/kernel/timer.c index 16f084fa3..096144210 100644 --- a/so3/kernel/timer.c +++ b/so3/kernel/timer.c @@ -410,7 +410,7 @@ void timer_init(void) /* * This function gets the current time and put it in the parameter tv */ -int do_get_time_of_day(struct timespec *ts) +SYSCALL_DEFINE1(gettimeofday, struct timespec *, ts) { u64 time; @@ -434,7 +434,7 @@ int do_get_time_of_day(struct timespec *ts) * * Currently, we only support CLOCK_MONOTONIC since we do not manage a RTC yet. */ -int do_get_clock_time(int clk_id, struct timespec *ts) +SYSCALL_DEFINE2(clock_gettime, int, clk_id, struct timespec *, ts) { u64 time; diff --git a/so3/net/net.c b/so3/net/net.c index dbeb479cc..f7064b255 100644 --- a/so3/net/net.c +++ b/so3/net/net.c @@ -368,7 +368,7 @@ struct file_operations *register_sock(void) /**************************** Syscall implementation ****************************/ -int do_socket(int domain, int type, int protocol) +SYSCALL_DEFINE3(socket, int, domain, int, type, int, protocol) { int fd, gfd, lwip_fd; struct file_operations *fops; @@ -403,7 +403,7 @@ int do_socket(int domain, int type, int protocol) return fd; } -int do_connect(int sockfd, const struct sockaddr *addr, socklen_t namelen) +SYSCALL_DEFINE3(connect, int, sockfd, const struct sockaddr *, addr, socklen_t, namelen) { struct sockaddr_in addr_lwip; struct sockaddr *addr_ptr; @@ -415,7 +415,7 @@ int do_connect(int sockfd, const struct sockaddr *addr, socklen_t namelen) return lwip_connect(lwip_fd, addr_ptr, namelen); } -int do_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) +SYSCALL_DEFINE3(bind, int, sockfd, const struct sockaddr *, addr, socklen_t, addrlen) { struct sockaddr_in addr_lwip; struct sockaddr *addr_ptr; @@ -427,14 +427,14 @@ int do_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) return lwip_bind(lwip_fd, addr_ptr, addrlen); } -int do_listen(int sockfd, int backlog) +SYSCALL_DEFINE2(listen, int, sockfd, int, backlog) { int lwip_fd = get_lwip_fd(sockfd); return lwip_listen(lwip_fd, backlog); } -int do_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) +SYSCALL_DEFINE3(accept, int, sockfd, struct sockaddr *, addr, socklen_t *, addrlen) { int fd, gfd, lwip_fd, lwip_bind_fd; struct file_operations *fops; @@ -478,28 +478,28 @@ int do_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) return fd; } -int do_recv(int sockfd, void *mem, size_t len, int flags) +SYSCALL_DEFINE4(recv, int, sockfd, void *, mem, size_t, len, int, flags) { int lwip_fd = get_lwip_fd(sockfd); return lwip_recv(lwip_fd, mem, len, flags); } -int do_recvfrom(int sockfd, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) +SYSCALL_DEFINE6(recvfrom, int, sockfd, void *, mem, size_t, len, int, flags, struct sockaddr *, from, socklen_t *, fromlen) { int lwip_fd = get_lwip_fd(sockfd); return lwip_recvfrom(lwip_fd, mem, len, flags, from, fromlen); } -int do_send(int sockfd, const void *dataptr, size_t size, int flags) +SYSCALL_DEFINE4(send, int, sockfd, const void *, dataptr, size_t, size, int, flags) { int lwip_fd = get_lwip_fd(sockfd); return lwip_send(lwip_fd, dataptr, size, flags); } -int do_sendto(int sockfd, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen) +SYSCALL_DEFINE6(sendto, int, sockfd, const void *, dataptr, size_t, size, int, flags, const struct sockaddr *, to, socklen_t, tolen) { struct sockaddr_in to_lwip; int lwip_fd = get_lwip_fd(sockfd); @@ -509,7 +509,7 @@ int do_sendto(int sockfd, const void *dataptr, size_t size, int flags, const str return lwip_sendto(lwip_fd, dataptr, size, flags, (struct sockaddr *) &to_lwip, tolen); } -int do_setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen) +SYSCALL_DEFINE5(setsockopt, int, sockfd, int, level, int, optname, const void *, optval, socklen_t, optlen) { int lwip_fd = get_lwip_fd(sockfd); From 10f4f5aea363f6c84d83159cc6dee22e67764b39 Mon Sep 17 00:00:00 2001 From: Clement Dieperink Date: Mon, 1 Sep 2025 10:43:41 +0200 Subject: [PATCH 2/2] correct format --- so3/fs/vfs.c | 8 ++-- so3/include/syscall.h | 69 +++++++++++++++++---------------- so3/kernel/syscalls.c | 88 +++++++++++++++++++++---------------------- so3/net/net.c | 3 +- 4 files changed, 86 insertions(+), 82 deletions(-) diff --git a/so3/fs/vfs.c b/so3/fs/vfs.c index 372bb6352..7da9cc765 100644 --- a/so3/fs/vfs.c +++ b/so3/fs/vfs.c @@ -751,7 +751,7 @@ SYSCALL_DEFINE5(mmap, addr_t, start, size_t, length, int, prot, int, fd, off_t, if (-1 == gfd) { printk("%s: could not get global fd.\n", __func__); set_errno(EBADF); - return (long)MAP_FAILED; + return (long) MAP_FAILED; } mutex_lock(&vfs_lock); @@ -760,7 +760,7 @@ SYSCALL_DEFINE5(mmap, addr_t, start, size_t, length, int, prot, int, fd, off_t, printk("%s: could not get device fops.\n", __func__); mutex_unlock(&vfs_lock); set_errno(EBADF); - return (long)MAP_FAILED; + return (long) MAP_FAILED; } mutex_unlock(&vfs_lock); @@ -774,11 +774,11 @@ SYSCALL_DEFINE5(mmap, addr_t, start, size_t, length, int, prot, int, fd, off_t, if (!fops->mmap) { printk("%s: device doesn't support mmap.\n", __func__); set_errno(EACCES); - return (long)MAP_FAILED; + return (long) MAP_FAILED; } /* Call the mmap fops that will do the actual mapping. */ - return (long)fops->mmap(fd, start, page_count, offset); + return (long) fops->mmap(fd, start, page_count, offset); } SYSCALL_DEFINE3(ioctl, int, fd, unsigned long, cmd, unsigned long, args) diff --git a/so3/include/syscall.h b/so3/include/syscall.h index 055ae0d24..e92cdb7ab 100644 --- a/so3/include/syscall.h +++ b/so3/include/syscall.h @@ -45,18 +45,18 @@ * @param t Type of the function arguments * @param n name of the function arguments */ -#define __MAP1(m,t,n) m(t,n) -#define __MAP2(m,t,n,...) m(t,n), __MAP1(m,__VA_ARGS__) -#define __MAP3(m,t,n,...) m(t,n), __MAP2(m,__VA_ARGS__) -#define __MAP4(m,t,n,...) m(t,n), __MAP3(m,__VA_ARGS__) -#define __MAP5(m,t,n,...) m(t,n), __MAP4(m,__VA_ARGS__) -#define __MAP6(m,t,n,...) m(t,n), __MAP5(m,__VA_ARGS__) -#define __MAP(x,m,...) __MAP##x(m,__VA_ARGS__) +#define __MAP1(m, t, n) m(t, n) +#define __MAP2(m, t, n, ...) m(t, n), __MAP1(m, __VA_ARGS__) +#define __MAP3(m, t, n, ...) m(t, n), __MAP2(m, __VA_ARGS__) +#define __MAP4(m, t, n, ...) m(t, n), __MAP3(m, __VA_ARGS__) +#define __MAP5(m, t, n, ...) m(t, n), __MAP4(m, __VA_ARGS__) +#define __MAP6(m, t, n, ...) m(t, n), __MAP5(m, __VA_ARGS__) +#define __MAP(x, m, ...) __MAP##x(m, __VA_ARGS__) /** Macros to map type and name with __MAP */ -#define __M_DECL(t,n) t n -#define __M_LONG(t,n) long n -#define __M_ARGS(t,n) n +#define __M_DECL(t, n) t n +#define __M_LONG(t, n) long n +#define __M_ARGS(t, n) n /** * Map syscall arguments by casting them for function call. @@ -68,13 +68,13 @@ * @param n name of the function arguments, not use but allow * to use same __VA_ARGS__ as in __MAP() */ -#define __MAP_ARGS1(x,args,t,n) (t)args[x-1] -#define __MAP_ARGS2(x,args,t,n,...) (t)args[x-2], __MAP_ARGS1(x,args,__VA_ARGS__) -#define __MAP_ARGS3(x,args,t,n,...) (t)args[x-3], __MAP_ARGS2(x,args,__VA_ARGS__) -#define __MAP_ARGS4(x,args,t,n,...) (t)args[x-4], __MAP_ARGS3(x,args,__VA_ARGS__) -#define __MAP_ARGS5(x,args,t,n,...) (t)args[x-5], __MAP_ARGS4(x,args,__VA_ARGS__) -#define __MAP_ARGS6(x,args,t,n,...) (t)args[x-6], __MAP_ARGS5(x,args,__VA_ARGS__) -#define __MAP_ARGS(x,args,...) __MAP_ARGS##x((x),(args),__VA_ARGS__) +#define __MAP_ARGS1(x, args, t, n) (t) args[x - 1] +#define __MAP_ARGS2(x, args, t, n, ...) (t) args[x - 2], __MAP_ARGS1(x, args, __VA_ARGS__) +#define __MAP_ARGS3(x, args, t, n, ...) (t) args[x - 3], __MAP_ARGS2(x, args, __VA_ARGS__) +#define __MAP_ARGS4(x, args, t, n, ...) (t) args[x - 4], __MAP_ARGS3(x, args, __VA_ARGS__) +#define __MAP_ARGS5(x, args, t, n, ...) (t) args[x - 5], __MAP_ARGS4(x, args, __VA_ARGS__) +#define __MAP_ARGS6(x, args, t, n, ...) (t) args[x - 6], __MAP_ARGS5(x, args, __VA_ARGS__) +#define __MAP_ARGS(x, args, ...) __MAP_ARGS##x((x), (args), __VA_ARGS__) /** * Syscall functions declaration and definitions helper. @@ -88,26 +88,29 @@ * arguments define like a normal function. That function is automatically * called by __sys_SYCALL_NAME with the correct argument number and cast. */ -#define SYSCALL_DECLARE(name,...) \ +#define SYSCALL_DECLARE(name, ...) \ long __sys_##name(syscall_args_t *args); \ inline long do_##name(__VA_ARGS__); -#define SYSCALL_DEFINE0(name) \ - long __sys_##name(syscall_args_t *unused) { return do_##name(); } \ +#define SYSCALL_DEFINE0(name) \ + long __sys_##name(syscall_args_t *unused) \ + { \ + return do_##name(); \ + } \ inline long do_##name(void) -#define SYSCALL_DEFINE1(...) __SYSCALL_DEFINEx(1,__VA_ARGS__) -#define SYSCALL_DEFINE2(...) __SYSCALL_DEFINEx(2,__VA_ARGS__) -#define SYSCALL_DEFINE3(...) __SYSCALL_DEFINEx(3,__VA_ARGS__) -#define SYSCALL_DEFINE4(...) __SYSCALL_DEFINEx(4,__VA_ARGS__) -#define SYSCALL_DEFINE5(...) __SYSCALL_DEFINEx(5,__VA_ARGS__) -#define SYSCALL_DEFINE6(...) __SYSCALL_DEFINEx(6,__VA_ARGS__) - -#define __SYSCALL_DEFINEx(x,name,...) \ - long __sys_##name(syscall_args_t *args) \ - { \ - return do_##name(__MAP_ARGS(x,args->args,__VA_ARGS__)); \ - } \ - inline long do_##name(__MAP(x,__M_DECL,__VA_ARGS__)) +#define SYSCALL_DEFINE1(...) __SYSCALL_DEFINEx(1, __VA_ARGS__) +#define SYSCALL_DEFINE2(...) __SYSCALL_DEFINEx(2, __VA_ARGS__) +#define SYSCALL_DEFINE3(...) __SYSCALL_DEFINEx(3, __VA_ARGS__) +#define SYSCALL_DEFINE4(...) __SYSCALL_DEFINEx(4, __VA_ARGS__) +#define SYSCALL_DEFINE5(...) __SYSCALL_DEFINEx(5, __VA_ARGS__) +#define SYSCALL_DEFINE6(...) __SYSCALL_DEFINEx(6, __VA_ARGS__) + +#define __SYSCALL_DEFINEx(x, name, ...) \ + long __sys_##name(syscall_args_t *args) \ + { \ + return do_##name(__MAP_ARGS(x, args->args, __VA_ARGS__)); \ + } \ + inline long do_##name(__MAP(x, __M_DECL, __VA_ARGS__)) typedef struct { unsigned long args[6]; diff --git a/so3/kernel/syscalls.c b/so3/kernel/syscalls.c index 596db0105..22c0f2332 100644 --- a/so3/kernel/syscalls.c +++ b/so3/kernel/syscalls.c @@ -38,61 +38,61 @@ extern uint32_t __get_syscall_stack_arg(uint32_t nr); extern void test_malloc(int test_no); static const syscall_fn_t syscall_table[NR_SYSCALLS] = { - [0 ... NR_SYSCALLS - 1] = NULL, + [0 ... NR_SYSCALLS - 1] = NULL, #ifdef CONFIG_MMU - [SYSCALL_GETPID] = __sys_getpid, - [SYSCALL_GETTIMEOFDAY] = __sys_gettimeofday, - [SYSCALL_CLOCK_GETTIME] = __sys_clock_gettime, - [SYSCALL_EXIT] = __sys_exit, - [SYSCALL_EXECVE] = __sys_execve, - [SYSCALL_FORK] = __sys_fork, - [SYSCALL_WAITPID] = __sys_waitpid, - [SYSCALL_PTRACE] = __sys_ptrace, + [SYSCALL_GETPID] = __sys_getpid, + [SYSCALL_GETTIMEOFDAY] = __sys_gettimeofday, + [SYSCALL_CLOCK_GETTIME] = __sys_clock_gettime, + [SYSCALL_EXIT] = __sys_exit, + [SYSCALL_EXECVE] = __sys_execve, + [SYSCALL_FORK] = __sys_fork, + [SYSCALL_WAITPID] = __sys_waitpid, + [SYSCALL_PTRACE] = __sys_ptrace, #endif - [SYSCALL_READ] = __sys_read, - [SYSCALL_WRITE] = __sys_write, - [SYSCALL_OPEN] = __sys_open, - [SYSCALL_CLOSE] = __sys_close, - [SYSCALL_THREAD_CREATE] = __sys_thread_create, - [SYSCALL_THREAD_JOIN] = __sys_thread_join, - [SYSCALL_THREAD_EXIT] = __sys_thread_exit, - [SYSCALL_THREAD_YIELD] = __sys_thread_yield, - [SYSCALL_READDIR] = __sys_readdir, - [SYSCALL_IOCTL] = __sys_ioctl, - [SYSCALL_FCNTL] = __sys_fcntl, - [SYSCALL_LSEEK] = __sys_lseek, + [SYSCALL_READ] = __sys_read, + [SYSCALL_WRITE] = __sys_write, + [SYSCALL_OPEN] = __sys_open, + [SYSCALL_CLOSE] = __sys_close, + [SYSCALL_THREAD_CREATE] = __sys_thread_create, + [SYSCALL_THREAD_JOIN] = __sys_thread_join, + [SYSCALL_THREAD_EXIT] = __sys_thread_exit, + [SYSCALL_THREAD_YIELD] = __sys_thread_yield, + [SYSCALL_READDIR] = __sys_readdir, + [SYSCALL_IOCTL] = __sys_ioctl, + [SYSCALL_FCNTL] = __sys_fcntl, + [SYSCALL_LSEEK] = __sys_lseek, #ifdef CONFIG_IPC_PIPE - [SYSCALL_PIPE] = __sys_pipe, + [SYSCALL_PIPE] = __sys_pipe, #endif - [SYSCALL_DUP] = __sys_dup, - [SYSCALL_DUP2] = __sys_dup2, - [SYSCALL_STAT] = __sys_stat, - [SYSCALL_MMAP] = __sys_mmap, - [SYSCALL_NANOSLEEP] = __sys_nanosleep, + [SYSCALL_DUP] = __sys_dup, + [SYSCALL_DUP2] = __sys_dup2, + [SYSCALL_STAT] = __sys_stat, + [SYSCALL_MMAP] = __sys_mmap, + [SYSCALL_NANOSLEEP] = __sys_nanosleep, #ifdef CONFIG_PROC_ENV - [SYSCALL_SBRK] = __sys_sbrk, + [SYSCALL_SBRK] = __sys_sbrk, #endif - [SYSCALL_MUTEX_LOCK] = __sys_mutex_lock, - [SYSCALL_MUTEX_UNLOCK] = __sys_mutex_unlock, + [SYSCALL_MUTEX_LOCK] = __sys_mutex_lock, + [SYSCALL_MUTEX_UNLOCK] = __sys_mutex_unlock, #ifdef CONFIG_IPC_SIGNAL - [SYSCALL_SIGACTION] = __sys_sigaction, - [SYSCALL_KILL] = __sys_kill, - [SYSCALL_SIGRETURN] = __sys_sigreturn, + [SYSCALL_SIGACTION] = __sys_sigaction, + [SYSCALL_KILL] = __sys_kill, + [SYSCALL_SIGRETURN] = __sys_sigreturn, #endif #ifdef CONFIG_NET - [SYSCALL_SOCKET] = __sys_socket, - [SYSCALL_BIND] = __sys_bind, - [SYSCALL_LISTEN] = __sys_listen, - [SYSCALL_ACCEPT] = __sys_accept, - [SYSCALL_CONNECT] = __sys_connect, - [SYSCALL_RECV] = __sys_recv, - [SYSCALL_SEND] = __sys_send, - [SYSCALL_SENDTO] = __sys_sendto, - [SYSCALL_SETSOCKOPT] = __sys_setsockopt, - [SYSCALL_RECVFROM] = __sys_recvfrom, + [SYSCALL_SOCKET] = __sys_socket, + [SYSCALL_BIND] = __sys_bind, + [SYSCALL_LISTEN] = __sys_listen, + [SYSCALL_ACCEPT] = __sys_accept, + [SYSCALL_CONNECT] = __sys_connect, + [SYSCALL_RECV] = __sys_recv, + [SYSCALL_SEND] = __sys_send, + [SYSCALL_SENDTO] = __sys_sendto, + [SYSCALL_SETSOCKOPT] = __sys_setsockopt, + [SYSCALL_RECVFROM] = __sys_recvfrom, #endif - [SYSCALL_SYSINFO] = __sys_sysinfo, + [SYSCALL_SYSINFO] = __sys_sysinfo, }; /* diff --git a/so3/net/net.c b/so3/net/net.c index f7064b255..139374cc8 100644 --- a/so3/net/net.c +++ b/so3/net/net.c @@ -499,7 +499,8 @@ SYSCALL_DEFINE4(send, int, sockfd, const void *, dataptr, size_t, size, int, fla return lwip_send(lwip_fd, dataptr, size, flags); } -SYSCALL_DEFINE6(sendto, int, sockfd, const void *, dataptr, size_t, size, int, flags, const struct sockaddr *, to, socklen_t, tolen) +SYSCALL_DEFINE6(sendto, int, sockfd, const void *, dataptr, size_t, size, int, flags, const struct sockaddr *, to, socklen_t, + tolen) { struct sockaddr_in to_lwip; int lwip_fd = get_lwip_fd(sockfd);