diff --git a/docs/SYSCALLS.md b/docs/SYSCALLS.md index 1cb5e0d..1630958 100644 --- a/docs/SYSCALLS.md +++ b/docs/SYSCALLS.md @@ -2,16 +2,14 @@ The following table contains all of the system calls supported by PepperOS, as well as their arguments. The explanation for what every system call does is available as a comment above each function in corresponding files in the `src/syscall` folder. -Name | Number (%rax) | arg0 (%rdi) | arg1 (%rsi) | arg2 (%rdx) | -|---|---|---|---|---| -| sys_read | 0 | unsigned int fd | char* buf | size_t count | -| sys_write | 1 | unsigned int fd | const char* buf | size_t count | -| sys_open | 2 | const char* filename | int flags | | -| sys_close | 3 | unsigned int fd | | | - -| sys_lseek | 8 | unsigned int fd | int offset | int whence | -| sys_tell | 9 | unsigned int fd | -| sys_eof | 10 | unsigned int fd | +Name | Number (%rax) | arg0 (%rdi) | arg1 (%rsi) | arg2 (%rdx) | arg3 (%r10) | +|---|---|---|---|---|---| +| sys_read | 0 | unsigned int fd | char* buf | size_t count | | +| sys_write | 1 | unsigned int fd | const char* buf | size_t count | | +| sys_open | 2 | const char* filename | int flags | | | +| sys_close | 3 | unsigned int fd | | | | +| sys_lseek | 8 | unsigned int fd | int offset | int whence | | +| sys_tell | 9 | unsigned int fd | | | | +| sys_eof | 10 | unsigned int fd | | | | | sys_draw | 11 | const uint8_t* src | int width | int height | int channels | - -| sys_exit | 60 | int error_code | | | \ No newline at end of file +| sys_exit | 60 | int error_code | | | | \ No newline at end of file diff --git a/src/syscall/syscall.c b/src/syscall/syscall.c index bae2b12..c6f3c11 100644 --- a/src/syscall/syscall.c +++ b/src/syscall/syscall.c @@ -18,15 +18,15 @@ extern struct process* current_process; +int sys_read(unsigned int fd, char* buf, size_t count); +int sys_write(unsigned int fd, const char* buf, size_t count); int sys_open(const char* filename, int flags); int sys_close(unsigned int fd); int sys_lseek(unsigned int fd, int offset, int whence); int sys_tell(unsigned int fd); // needed by doom, therefore TOP PRIORITY int sys_eof(unsigned int fd); // same -int sys_read(unsigned int fd, char* buf, size_t count); -int sys_write(unsigned int fd, const char* buf, size_t count); -int sys_exit(int error_code); int sys_draw(const uint8_t* src, int width, int height, int channels); +int sys_exit(int error_code); /* * syscall_handler - System call dispatcher diff --git a/user/libc/syscall.h b/user/libc/syscall.h index 21861ae..b6f46a7 100644 --- a/user/libc/syscall.h +++ b/user/libc/syscall.h @@ -1,21 +1,79 @@ -#pragma once +/* + * @author xamidev + * @brief System call wrappers for userspace + * @license GPL-3.0-only + */ -// 3 because 3 arguments to the call, get it?? +#pragma once +// TODO: replace all ifndef/define/endif by pragma once.. + +#include +#include + +// 3-args syscall static inline long syscall3(long n, long a, long b, long c) { long ret; __asm__ volatile ( "int $0x80" : "=a"(ret) - : "a"(n), "D"(a), "S"(b), "d"(c) + : "a"(n), "D"(a), "S"(b), "d"(c) // a = rax, D = rdi, S = rsi, d = rdx : "memory" ); return ret; } -static inline void write(int fd, const char* buf, long len) { - syscall3(1, fd, (long)buf, len); +// 4-args syscall +static inline long syscall4(long n, long a, long b, long c, long d) { + long ret; + register long r10 __asm__("r10") = d; + + __asm__ volatile ( + "int $0x80" + : "=a"(ret) + : "a"(n), "D"(a), "S"(b), "d"(c), "r"(r10) + : "memory" + ); + + return ret; +} + +// Single-arg syscall +static inline long syscall1(long n, long a) { + return syscall3(n, a, 0, 0); +} + +static inline int write(int fd, const char* buf, long len) { + return (int)syscall3(1, fd, (long)buf, len); +} + +static inline int read(int fd, char* buf, long len) { + return (int)syscall3(0, fd, (long)buf, len); +} + +static inline int open(const char* path, int flags) { + return (int)syscall3(2, (long)path, flags, 0); +} + +static inline int close(unsigned int fd) { + return (int)syscall3(3, fd, 0, 0); +} + +static inline int seek(int fd, int offset, int whence) { + return (int)syscall3(8, fd, offset, whence); +} + +static inline int tell(unsigned int fd) { + return (int)syscall1(9, fd); +} + +static inline int eof(unsigned int fd) { + return (int)syscall1(10, fd); +} + +static inline int draw(const unsigned char* buf, int width, int height, int channels) { + return (int)syscall4(11, (long)buf, width, height, channels); } static inline void exit(int code) {