From 09ab2f1a838d8776cc09e4c25ec79eb22441e77d Mon Sep 17 00:00:00 2001 From: Marvin Friedrich Date: Tue, 15 Sep 2026 22:21:27 +0200 Subject: [PATCH] todo --- include/zinnia/archctl.h | 5 +- include/zinnia/channel.h | 30 ++- include/zinnia/futex.h | 9 +- include/zinnia/handle.h | 13 +- include/zinnia/mem.h | 18 +- include/zinnia/namespace.h | 8 +- include/zinnia/random.h | 4 +- include/zinnia/resource.h | 16 ++ include/zinnia/status.h | 2 - include/zinnia/syscall.h | 236 ++++++++++++++++++ include/zinnia/syscall_numbers.h | 38 +++ .../kernel => include/zinnia}/syscall_stubs.h | 0 include/zinnia/system.h | 4 - kernel/vdso/archctl.c | 10 - kernel/vdso/channel.c | 45 ---- kernel/vdso/futex.c | 16 -- kernel/vdso/handle.c | 22 -- kernel/vdso/mem.c | 35 --- kernel/vdso/namespace.c | 16 -- kernel/vdso/status.c | 37 --- lib/freestanding/entry.c | 1 - lib/freestanding/meson.build | 8 - lib/freestanding/vdso.c | 138 ---------- lib/meson.build | 2 - 24 files changed, 356 insertions(+), 357 deletions(-) create mode 100644 include/zinnia/resource.h create mode 100644 include/zinnia/syscall.h create mode 100644 include/zinnia/syscall_numbers.h rename {kernel/include/kernel => include/zinnia}/syscall_stubs.h (100%) delete mode 100644 kernel/vdso/archctl.c delete mode 100644 kernel/vdso/channel.c delete mode 100644 kernel/vdso/futex.c delete mode 100644 kernel/vdso/handle.c delete mode 100644 kernel/vdso/mem.c delete mode 100644 kernel/vdso/namespace.c delete mode 100644 kernel/vdso/status.c delete mode 100644 lib/freestanding/entry.c delete mode 100644 lib/freestanding/meson.build delete mode 100644 lib/freestanding/vdso.c diff --git a/include/zinnia/archctl.h b/include/zinnia/archctl.h index ee4f4e0..9b95514 100644 --- a/include/zinnia/archctl.h +++ b/include/zinnia/archctl.h @@ -4,6 +4,7 @@ #define ZINNIA_ARCHCTL_H #include +#include #ifdef __cplusplus extern "C" { @@ -19,7 +20,9 @@ typedef enum { } zn_archctl_t; // Performs an architecture-dependent operation identified by `op`. -zn_status_t zn_archctl(zn_archctl_t op, void* value); +static inline zn_status_t zn_archctl(zn_archctl_t op, void* value) { + return zn_syscall2(op, value, ZN_SYSCALL_ARCHCTL); +} #ifdef __cplusplus } diff --git a/include/zinnia/channel.h b/include/zinnia/channel.h index 81ddbb8..48eab4b 100644 --- a/include/zinnia/channel.h +++ b/include/zinnia/channel.h @@ -5,6 +5,7 @@ #include #include +#include #include #ifdef __cplusplus @@ -17,20 +18,28 @@ enum zn_channel_flags { }; // Creates a new channel. -zn_status_t zn_channel_create(enum zn_channel_flags flags, zn_handle_t* endpoint0, zn_handle_t* endpoint1); +static inline zn_status_t zn_channel_create( + enum zn_channel_flags flags, + zn_handle_t* endpoint0, + zn_handle_t* endpoint1 +) { + return zn_syscall3(flags, endpoint0, endpoint1, ZN_SYSCALL_CHANNEL_CREATE); +} // Notifies the peer that there is new data available. // The kernel only copies the first `num_handles` handles and `num_bytes` bytes. -zn_status_t zn_channel_write( +static inline zn_status_t zn_channel_write( zn_handle_t channel, const zn_handle_t* handles, const void* bytes, size_t num_handles, size_t num_bytes -); +) { + return zn_syscall5(channel, handles, bytes, num_handles, num_bytes, ZN_SYSCALL_CHANNEL_WRITE); +} // Waits for a new message to appear in the channel. -zn_status_t zn_channel_read( +static inline zn_status_t zn_channel_read( zn_handle_t channel, zn_handle_t* handles, void* bytes, @@ -38,7 +47,18 @@ zn_status_t zn_channel_read( size_t num_bytes, size_t* read_handles, size_t* read_bytes -); +) { + return zn_syscall7( + channel, + handles, + bytes, + num_handles, + num_bytes, + read_handles, + read_bytes, + ZN_SYSCALL_CHANNEL_READ + ); +} #ifdef __cplusplus } diff --git a/include/zinnia/futex.h b/include/zinnia/futex.h index 6f1a2b3..67e4f36 100644 --- a/include/zinnia/futex.h +++ b/include/zinnia/futex.h @@ -4,6 +4,7 @@ #define ZINNIA_FUTEX_H #include +#include #include #ifdef __cplusplus @@ -12,10 +13,14 @@ extern "C" { // Blocks the calling thread if *addr == expected. // Returns immediately if the value at addr has changed. -zn_status_t zn_futex_wait(int32_t* addr, int32_t expected); +static inline zn_status_t zn_futex_wait(int32_t* addr, int32_t expected) { + return zn_syscall2(addr, expected, ZN_SYSCALL_FUTEX_WAIT); +} // Wakes up to `count` threads waiting on the given futex address. -zn_status_t zn_futex_wake(int32_t* addr, int32_t count); +static inline zn_status_t zn_futex_wake(int32_t* addr, int32_t count) { + return zn_syscall2(addr, count, ZN_SYSCALL_FUTEX_WAKE); +} #ifdef __cplusplus } diff --git a/include/zinnia/handle.h b/include/zinnia/handle.h index 55413fe..6a1f80b 100644 --- a/include/zinnia/handle.h +++ b/include/zinnia/handle.h @@ -5,6 +5,7 @@ #include #include +#include #include #ifdef __cplusplus @@ -21,16 +22,22 @@ typedef int32_t zn_handle_t; #define ZN_HANDLE_ZERO_VMO ((zn_handle_t)(-4)) // Checks an object handle for validity. -zn_status_t zn_handle_validate(zn_handle_t handle); +zn_status_t zn_handle_validate(zn_handle_t handle) { + return zn_syscall1(handle, ZN_SYSCALL_HANDLE_VALIDATE); +} // Drops an object handle. All further references using this handle are invalid. // The numerical value may become valid again, but it is an error to keep using it. // The underlying object gets freed only once no other handle references it. -zn_status_t zn_handle_drop(zn_handle_t handle); +zn_status_t zn_handle_drop(zn_handle_t handle) { + return zn_syscall1(handle, ZN_SYSCALL_HANDLE_DROP); +} // Creates a new handle pointing to the same object as pointed to // by the original handle. The new handle may obtain new rights. -zn_status_t zn_handle_clone(zn_handle_t handle, zn_rights_t cloned_rights, zn_handle_t* cloned); +zn_status_t zn_handle_clone(zn_handle_t handle, zn_rights_t cloned_rights, zn_handle_t* cloned) { + return zn_syscall3(handle, cloned_rights, cloned, ZN_SYSCALL_HANDLE_CLONE); +} #ifdef __cplusplus } diff --git a/include/zinnia/mem.h b/include/zinnia/mem.h index 51aadfa..850e928 100644 --- a/include/zinnia/mem.h +++ b/include/zinnia/mem.h @@ -32,23 +32,31 @@ enum zn_vm_flags { }; // Creates a new virtual memory object. -zn_status_t zn_vmo_create(size_t length, zn_handle_t* out); +static inline zn_status_t zn_vmo_create(size_t length, zn_handle_t* out) { + return zn_syscall2(length, out, ZN_SYSCALL_VMO_CREATE); +} // Creates a new virtual memory object which points to a contiguous phyiscal memory region. -zn_status_t zn_vmo_create_phys(uintptr_t phys_addr, size_t length, zn_handle_t* out); +static inline zn_status_t zn_vmo_create_phys(uintptr_t phys_addr, size_t length, zn_handle_t* out) { + return zn_syscall3(phys_addr, length, out, ZN_SYSCALL_VMO_CREATE_PHYS); +} // Maps `bytes` of `vmo` at `vmo_offset` to `addr` in `vas`. -zn_status_t zn_vmo_map( +static inline zn_status_t zn_vmo_map( zn_handle_t vmo, zn_handle_t vas, uintptr_t vmo_offset, uintptr_t* addr, size_t bytes, enum zn_vm_flags flags -); +) { + return zn_syscall6(vmo, vas, vmo_offset, addr, bytes, flags, ZN_SYSCALL_VMO_MAP); +} // Creates a new virtual address space. -zn_status_t zn_vas_create(zn_handle_t* out); +static inline zn_status_t zn_vas_create(zn_handle_t* out) { + return zn_syscall1(out, ZN_SYSCALL_VAS_CREATE); +} #ifdef __cplusplus } diff --git a/include/zinnia/namespace.h b/include/zinnia/namespace.h index 8b4d46e..58e93de 100644 --- a/include/zinnia/namespace.h +++ b/include/zinnia/namespace.h @@ -11,11 +11,15 @@ extern "C" { #endif // Creates a new namespace. -zn_status_t zn_ns_create(zn_handle_t* out); +static inline zn_status_t zn_ns_create(zn_handle_t* out) { + return ZN_ERR_UNSUPPORTED; +} // Moves a handle to another namespace. // The handle must have the `ZN_RIGHT_MOVE` right. -zn_status_t zn_ns_move(zn_handle_t handle, zn_handle_t target_ns); +static inline zn_status_t zn_ns_move(zn_handle_t handle, zn_handle_t target_ns) { + return ZN_ERR_UNSUPPORTED; +} #ifdef __cplusplus } diff --git a/include/zinnia/random.h b/include/zinnia/random.h index 0baed8f..ab48812 100644 --- a/include/zinnia/random.h +++ b/include/zinnia/random.h @@ -10,9 +10,7 @@ extern "C" { #endif -enum { - ZN_RANDOM_MAX_ENTROPY = 0x1000 -}; +#define ZN_RANDOM_MAX_ENTROPY 0x1000 // Stores random bytes in a buffer. zn_status_t zn_random_get(void* addr, size_t len); diff --git a/include/zinnia/resource.h b/include/zinnia/resource.h new file mode 100644 index 0000000..b2f2bd9 --- /dev/null +++ b/include/zinnia/resource.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT + +#ifndef ZINNIA_RESOURCE_H +#define ZINNIA_RESOURCE_H + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/zinnia/status.h b/include/zinnia/status.h index 5290a47..6acb2ea 100644 --- a/include/zinnia/status.h +++ b/include/zinnia/status.h @@ -36,8 +36,6 @@ typedef enum { ZN_ERR_ALREADY_EXISTS = -11, } zn_status_t; -const char* zn_status_to_string(zn_status_t err); - #ifdef __cplusplus } #endif diff --git a/include/zinnia/syscall.h b/include/zinnia/syscall.h new file mode 100644 index 0000000..c9c3150 --- /dev/null +++ b/include/zinnia/syscall.h @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: MIT + +#ifndef ZINNIA_SYSCALL_H +#define ZINNIA_SYSCALL_H + +#include +#include +#include + +typedef uintptr_t zn_arg_t; + +#ifdef __x86_64__ +#define ASM_REG_NUM "rax" +#define ASM_REG_RET "rax" +#define ASM_REG_A0 "rdi" +#define ASM_REG_A1 "rsi" +#define ASM_REG_A2 "rdx" +#define ASM_REG_A3 "r9" +#define ASM_REG_A4 "r8" +#define ASM_REG_A5 "r10" +#define ASM_REG_A6 "r12" +#define ASM_REG_A7 "r13" +#define ASM_SYSCALL "syscall" +#define ASM_CLOBBER "rcx", "r11" +#elif defined(__aarch64__) +#define ASM_REG_NUM "x8" +#define ASM_REG_RET "x0" +#define ASM_REG_A0 "x0" +#define ASM_REG_A1 "x1" +#define ASM_REG_A2 "x2" +#define ASM_REG_A3 "x3" +#define ASM_REG_A4 "x4" +#define ASM_REG_A5 "x5" +#define ASM_REG_A6 "x6" +#define ASM_REG_A7 "x7" +#define ASM_SYSCALL "svc 0" +#define ASM_CLOBBER +#elif defined(__riscv) && (__riscv_xlen == 64) +#define ASM_REG_NUM "t3" +#define ASM_REG_RET "a0" +#define ASM_REG_A0 "a0" +#define ASM_REG_A1 "a1" +#define ASM_REG_A2 "a2" +#define ASM_REG_A3 "a3" +#define ASM_REG_A4 "a4" +#define ASM_REG_A5 "a5" +#define ASM_REG_A5 "a6" +#define ASM_REG_A5 "a7" +#define ASM_SYSCALL "ecall" +#define ASM_CLOBBER +#elif defined(__loongarch64) +#define ASM_REG_NUM "a7" +#define ASM_REG_RET "a0" +#define ASM_REG_A0 "a0" +#define ASM_REG_A1 "a1" +#define ASM_REG_A2 "a2" +#define ASM_REG_A3 "a3" +#define ASM_REG_A4 "a4" +#define ASM_REG_A5 "a5" +// TODO: Define ABI +#define ASM_REG_A6 TODO +#define ASM_REG_A7 TODO +#define ASM_SYSCALL "syscall 0" +#define ASM_CLOBBER +#else +#error "Unsupported architecture!" +#endif + +static inline zn_status_t zn_syscall0(zn_syscall_t num) { + register zn_syscall_t rnum asm(ASM_REG_NUM) = num; + register zn_status_t value asm(ASM_REG_RET); + asm volatile(ASM_SYSCALL : "=r"(value) : "r"(rnum) : "memory", ASM_CLOBBER); + return value; +} + +static inline zn_status_t zn_syscall1(zn_arg_t a0, zn_syscall_t num) { + register zn_syscall_t rnum asm(ASM_REG_NUM) = num; + register zn_status_t value asm(ASM_REG_RET); + register zn_arg_t r0 asm(ASM_REG_A0) = a0; + asm volatile(ASM_SYSCALL : "=r"(value) : "r"(rnum), "r"(r0) : "memory", ASM_CLOBBER); + return value; +} +#define zn_syscall1(a0, num) zn_syscall1((zn_arg_t)a0, num) + +static inline zn_status_t zn_syscall2(zn_arg_t a0, zn_arg_t a1, zn_syscall_t num) { + register zn_syscall_t rnum asm(ASM_REG_NUM) = num; + register zn_status_t value asm(ASM_REG_RET); + register zn_arg_t r0 asm(ASM_REG_A0) = a0; + register zn_arg_t r1 asm(ASM_REG_A1) = a1; + asm volatile(ASM_SYSCALL : "=r"(value) : "r"(rnum), "r"(r0), "r"(r1) : "memory", ASM_CLOBBER); + return value; +} +#define zn_syscall2(a0, a1, num) zn_syscall2((zn_arg_t)a0, (zn_arg_t)a1, num) + +static inline zn_status_t zn_syscall3(zn_arg_t a0, zn_arg_t a1, zn_arg_t a2, zn_syscall_t num) { + register zn_syscall_t rnum asm(ASM_REG_NUM) = num; + register zn_status_t value asm(ASM_REG_RET); + register zn_arg_t r0 asm(ASM_REG_A0) = a0; + register zn_arg_t r1 asm(ASM_REG_A1) = a1; + register zn_arg_t r2 asm(ASM_REG_A2) = a2; + asm volatile(ASM_SYSCALL : "=r"(value) : "r"(rnum), "r"(r0), "r"(r1), "r"(r2) : "memory", ASM_CLOBBER); + return value; +} +#define zn_syscall3(a0, a1, a2, num) zn_syscall3((zn_arg_t)a0, (zn_arg_t)a1, (zn_arg_t)a2, num) + +static inline zn_status_t zn_syscall4(zn_arg_t a0, zn_arg_t a1, zn_arg_t a2, zn_arg_t a3, zn_syscall_t num) { + register zn_syscall_t rnum asm(ASM_REG_NUM) = num; + register zn_status_t value asm(ASM_REG_RET); + register zn_arg_t r0 asm(ASM_REG_A0) = a0; + register zn_arg_t r1 asm(ASM_REG_A1) = a1; + register zn_arg_t r2 asm(ASM_REG_A2) = a2; + register zn_arg_t r3 asm(ASM_REG_A3) = a3; + asm volatile(ASM_SYSCALL : "=r"(value) : "r"(rnum), "r"(r0), "r"(r1), "r"(r2), "r"(r3) : "memory", ASM_CLOBBER); + return value; +} +#define zn_syscall4(a0, a1, a2, a3, num) zn_syscall4((zn_arg_t)a0, (zn_arg_t)a1, (zn_arg_t)a2, (zn_arg_t)a3, num) + +static inline zn_status_t zn_syscall5( + zn_arg_t a0, + zn_arg_t a1, + zn_arg_t a2, + zn_arg_t a3, + zn_arg_t a4, + zn_syscall_t num +) { + register zn_syscall_t rnum asm(ASM_REG_NUM) = num; + register zn_status_t value asm(ASM_REG_RET); + register zn_arg_t r0 asm(ASM_REG_A0) = a0; + register zn_arg_t r1 asm(ASM_REG_A1) = a1; + register zn_arg_t r2 asm(ASM_REG_A2) = a2; + register zn_arg_t r3 asm(ASM_REG_A3) = a3; + register zn_arg_t r4 asm(ASM_REG_A4) = a4; + asm volatile(ASM_SYSCALL + : "=r"(value) + : "r"(rnum), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4) + : "memory", ASM_CLOBBER); + return value; +} +#define zn_syscall5(a0, a1, a2, a3, a4, num) \ + zn_syscall5((zn_arg_t)a0, (zn_arg_t)a1, (zn_arg_t)a2, (zn_arg_t)a3, (zn_arg_t)a4, num) + +static inline zn_status_t zn_syscall6( + zn_arg_t a0, + zn_arg_t a1, + zn_arg_t a2, + zn_arg_t a3, + zn_arg_t a4, + zn_arg_t a5, + zn_syscall_t num +) { + register zn_syscall_t rnum asm(ASM_REG_NUM) = num; + register zn_status_t value asm(ASM_REG_RET); + register zn_arg_t r0 asm(ASM_REG_A0) = a0; + register zn_arg_t r1 asm(ASM_REG_A1) = a1; + register zn_arg_t r2 asm(ASM_REG_A2) = a2; + register zn_arg_t r3 asm(ASM_REG_A3) = a3; + register zn_arg_t r4 asm(ASM_REG_A4) = a4; + register zn_arg_t r5 asm(ASM_REG_A5) = a5; + asm volatile(ASM_SYSCALL + : "=r"(value) + : "r"(rnum), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5) + : "memory", ASM_CLOBBER); + return value; +} +#define zn_syscall6(a0, a1, a2, a3, a4, a5, num) \ + zn_syscall6((zn_arg_t)a0, (zn_arg_t)a1, (zn_arg_t)a2, (zn_arg_t)a3, (zn_arg_t)a4, (zn_arg_t)a5, num) + +static inline zn_status_t zn_syscall7( + zn_arg_t a0, + zn_arg_t a1, + zn_arg_t a2, + zn_arg_t a3, + zn_arg_t a4, + zn_arg_t a5, + zn_arg_t a6, + zn_syscall_t num +) { + register zn_syscall_t rnum asm(ASM_REG_NUM) = num; + register zn_status_t value asm(ASM_REG_RET); + register zn_arg_t r0 asm(ASM_REG_A0) = a0; + register zn_arg_t r1 asm(ASM_REG_A1) = a1; + register zn_arg_t r2 asm(ASM_REG_A2) = a2; + register zn_arg_t r3 asm(ASM_REG_A3) = a3; + register zn_arg_t r4 asm(ASM_REG_A4) = a4; + register zn_arg_t r5 asm(ASM_REG_A5) = a5; + register zn_arg_t r6 asm(ASM_REG_A6) = a6; + asm volatile(ASM_SYSCALL + : "=r"(value) + : "r"(rnum), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5), "r"(r6) + : "memory", ASM_CLOBBER); + return value; +} +#define zn_syscall7(a0, a1, a2, a3, a4, a5, a6, num) \ + zn_syscall7((zn_arg_t)a0, (zn_arg_t)a1, (zn_arg_t)a2, (zn_arg_t)a3, (zn_arg_t)a4, (zn_arg_t)a5, (zn_arg_t)a6, num) + +static inline zn_status_t zn_syscall8( + zn_arg_t a0, + zn_arg_t a1, + zn_arg_t a2, + zn_arg_t a3, + zn_arg_t a4, + zn_arg_t a5, + zn_arg_t a6, + zn_arg_t a7, + zn_syscall_t num +) { + register zn_syscall_t rnum asm(ASM_REG_NUM) = num; + register zn_status_t value asm(ASM_REG_RET); + register zn_arg_t r0 asm(ASM_REG_A0) = a0; + register zn_arg_t r1 asm(ASM_REG_A1) = a1; + register zn_arg_t r2 asm(ASM_REG_A2) = a2; + register zn_arg_t r3 asm(ASM_REG_A3) = a3; + register zn_arg_t r4 asm(ASM_REG_A4) = a4; + register zn_arg_t r5 asm(ASM_REG_A5) = a5; + register zn_arg_t r6 asm(ASM_REG_A6) = a6; + register zn_arg_t r7 asm(ASM_REG_A7) = a7; + asm volatile(ASM_SYSCALL + : "=r"(value) + : "r"(rnum), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7) + : "memory", ASM_CLOBBER); + return value; +} +#define zn_syscall8(a0, a1, a2, a3, a4, a5, a6, a7, num) \ + zn_syscall8( \ + (zn_arg_t)a0, \ + (zn_arg_t)a1, \ + (zn_arg_t)a2, \ + (zn_arg_t)a3, \ + (zn_arg_t)a4, \ + (zn_arg_t)a5, \ + (zn_arg_t)a6, \ + (zn_arg_t)a7, \ + num \ + ) + +#endif diff --git a/include/zinnia/syscall_numbers.h b/include/zinnia/syscall_numbers.h new file mode 100644 index 0000000..0890122 --- /dev/null +++ b/include/zinnia/syscall_numbers.h @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT + +#ifndef ZINNIA_SYSCALL_NUMBERS_H +#define ZINNIA_SYSCALL_NUMBERS_H + +typedef enum { + ZN_SYSCALL_LOG, + ZN_SYSCALL_ARCHCTL, + ZN_SYSCALL_PAGE_SIZE, + ZN_SYSCALL_TIME, + + ZN_SYSCALL_HANDLE_VALIDATE, + ZN_SYSCALL_HANDLE_DROP, + ZN_SYSCALL_HANDLE_CLONE, + + ZN_SYSCALL_VAS_CREATE, + + ZN_SYSCALL_VMO_CREATE, + ZN_SYSCALL_VMO_CREATE_PHYS, + ZN_SYSCALL_VMO_MAP, + + ZN_SYSCALL_CHANNEL_CREATE, + ZN_SYSCALL_CHANNEL_WAIT, + ZN_SYSCALL_CHANNEL_READ, + ZN_SYSCALL_CHANNEL_WRITE, + + ZN_SYSCALL_THREAD_CREATE, + ZN_SYSCALL_THREAD_START, + ZN_SYSCALL_THREAD_EXIT, + + ZN_SYSCALL_RANDOM_GET, + ZN_SYSCALL_RANDOM_ENTROPY, + + ZN_SYSCALL_FUTEX_WAIT, + ZN_SYSCALL_FUTEX_WAKE, +} zn_syscall_t; + +#endif diff --git a/kernel/include/kernel/syscall_stubs.h b/include/zinnia/syscall_stubs.h similarity index 100% rename from kernel/include/kernel/syscall_stubs.h rename to include/zinnia/syscall_stubs.h diff --git a/include/zinnia/system.h b/include/zinnia/system.h index 5b7d883..d82793e 100644 --- a/include/zinnia/system.h +++ b/include/zinnia/system.h @@ -4,7 +4,6 @@ #define ZINNIA_SYSTEM_H #include -#include #include #ifdef __cplusplus @@ -20,9 +19,6 @@ size_t zn_page_size(); zn_status_t zn_powerctl(); -// Returns the current timestamp in nanoseconds. -uint64_t zn_time(); - #ifdef __cplusplus } #endif diff --git a/kernel/vdso/archctl.c b/kernel/vdso/archctl.c deleted file mode 100644 index 8486fc2..0000000 --- a/kernel/vdso/archctl.c +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT - -#include -#include - -zn_status_t zn_archctl(zn_archctl_t op, void* value) { - return zn_syscall2(op, value, ZN_SYSCALL_ARCHCTL); -} - -VDSO_SYMBOL(zn_archctl); diff --git a/kernel/vdso/channel.c b/kernel/vdso/channel.c deleted file mode 100644 index 81b7d70..0000000 --- a/kernel/vdso/channel.c +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: MIT - -#include -#include - -zn_status_t zn_channel_create(enum zn_channel_flags flags, zn_handle_t* endpoint0, zn_handle_t* endpoint1) { - return zn_syscall3(flags, endpoint0, endpoint1, ZN_SYSCALL_CHANNEL_CREATE); -} - -VDSO_SYMBOL(zn_channel_create); - -zn_status_t zn_channel_write( - zn_handle_t channel, - const zn_handle_t* handles, - const void* bytes, - size_t num_handles, - size_t num_bytes -) { - return zn_syscall5(channel, handles, bytes, num_handles, num_bytes, ZN_SYSCALL_CHANNEL_WRITE); -} - -VDSO_SYMBOL(zn_channel_write); - -zn_status_t zn_channel_read( - zn_handle_t channel, - zn_handle_t* handles, - void* bytes, - size_t num_handles, - size_t num_bytes, - size_t* read_handles, - size_t* read_bytes -) { - return zn_syscall7( - channel, - handles, - bytes, - num_handles, - num_bytes, - read_handles, - read_bytes, - ZN_SYSCALL_CHANNEL_READ - ); -} - -VDSO_SYMBOL(zn_channel_read); diff --git a/kernel/vdso/futex.c b/kernel/vdso/futex.c deleted file mode 100644 index aadb7d8..0000000 --- a/kernel/vdso/futex.c +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT - -#include -#include - -zn_status_t zn_futex_wait(int32_t* addr, int32_t expected) { - return zn_syscall2(addr, expected, ZN_SYSCALL_FUTEX_WAIT); -} - -VDSO_SYMBOL(zn_futex_wait); - -zn_status_t zn_futex_wake(int32_t* addr, int32_t count) { - return zn_syscall2(addr, count, ZN_SYSCALL_FUTEX_WAKE); -} - -VDSO_SYMBOL(zn_futex_wake); diff --git a/kernel/vdso/handle.c b/kernel/vdso/handle.c deleted file mode 100644 index 1035d70..0000000 --- a/kernel/vdso/handle.c +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: MIT - -#include -#include - -zn_status_t zn_handle_validate(zn_handle_t handle) { - return zn_syscall1(handle, ZN_SYSCALL_HANDLE_VALIDATE); -} - -VDSO_SYMBOL(zn_handle_validate); - -zn_status_t zn_handle_drop(zn_handle_t handle) { - return zn_syscall1(handle, ZN_SYSCALL_HANDLE_DROP); -} - -VDSO_SYMBOL(zn_handle_drop); - -zn_status_t zn_handle_clone(zn_handle_t handle, zn_rights_t cloned_rights, zn_handle_t* cloned) { - return zn_syscall3(handle, cloned_rights, cloned, ZN_SYSCALL_HANDLE_CLONE); -} - -VDSO_SYMBOL(zn_handle_clone); diff --git a/kernel/vdso/mem.c b/kernel/vdso/mem.c deleted file mode 100644 index ad54a3d..0000000 --- a/kernel/vdso/mem.c +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT - -#include -#include - -zn_status_t zn_vmo_create(size_t length, zn_handle_t* out) { - return zn_syscall2(length, out, ZN_SYSCALL_VMO_CREATE); -} - -VDSO_SYMBOL(zn_vmo_create); - -zn_status_t zn_vmo_create_phys(uintptr_t phys_addr, size_t length, zn_handle_t* out) { - return zn_syscall3(phys_addr, length, out, ZN_SYSCALL_VMO_CREATE_PHYS); -} - -VDSO_SYMBOL(zn_vmo_create_phys); - -zn_status_t zn_vmo_map( - zn_handle_t vmo, - zn_handle_t vas, - uintptr_t vmo_offset, - uintptr_t* addr, - size_t bytes, - enum zn_vm_flags flags -) { - return zn_syscall6(vmo, vas, vmo_offset, addr, bytes, flags, ZN_SYSCALL_VMO_MAP); -} - -VDSO_SYMBOL(zn_vmo_map); - -zn_status_t zn_vas_create(zn_handle_t* out) { - return zn_syscall1(out, ZN_SYSCALL_VAS_CREATE); -} - -VDSO_SYMBOL(zn_vas_create); diff --git a/kernel/vdso/namespace.c b/kernel/vdso/namespace.c deleted file mode 100644 index 00a80fa..0000000 --- a/kernel/vdso/namespace.c +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT - -#include -#include - -zn_status_t zn_ns_create(zn_handle_t* out) { - return ZN_ERR_UNSUPPORTED; -} - -VDSO_SYMBOL(zn_ns_create); - -zn_status_t zn_ns_move(zn_handle_t handle, zn_handle_t target_ns) { - return ZN_ERR_UNSUPPORTED; -} - -VDSO_SYMBOL(zn_ns_move); diff --git a/kernel/vdso/status.c b/kernel/vdso/status.c deleted file mode 100644 index 4566abd..0000000 --- a/kernel/vdso/status.c +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MIT - -#include -#include - -const char* zn_status_to_string(zn_status_t err) { - switch (err) { - case ZN_OK: - return "No error (OK)"; - case ZN_ERR_INTERNAL: - return "An internal error occured (INTERNAL)"; - case ZN_ERR_BAD_SYSCALL: - return "Syscall number is not a recognized syscall (BAD_SYSCALL)"; - case ZN_ERR_UNSUPPORTED: - return "This operation is not supported or implemented yet (UNSUPPORTED)"; - case ZN_ERR_NO_MEMORY: - return "System does not have enough free memory for this operation (NO_MEMORY)"; - case ZN_ERR_NO_HANDLES: - return "Process can not own any more handles (NO_HANDLES)"; - case ZN_ERR_INVALID: - return "One or more of the provided arguments is not valid (INVALID)"; - case ZN_ERR_BAD_RANGE: - return "Argument is outside of the range for valid values (BAD_RANGE)"; - case ZN_ERR_BAD_HANDLE: - return "Object handle does not name a valid object (BAD_HANDLE)"; - case ZN_ERR_BAD_PERMS: - return "Object has insufficient permissions for this operation (BAD_PERMS)"; - case ZN_ERR_BAD_BUFFER: - return "Buffer is not large enough or doesn't point to a valid memory region (BAD_BUFFER)"; - case ZN_ERR_ALREADY_EXISTS: - return "The resource already exists (ALREADY_EXISTS)"; - } - - return "Unknown error code"; -} - -VDSO_SYMBOL(zn_status_to_string); diff --git a/lib/freestanding/entry.c b/lib/freestanding/entry.c deleted file mode 100644 index 8b13789..0000000 --- a/lib/freestanding/entry.c +++ /dev/null @@ -1 +0,0 @@ - diff --git a/lib/freestanding/meson.build b/lib/freestanding/meson.build deleted file mode 100644 index 18da658..0000000 --- a/lib/freestanding/meson.build +++ /dev/null @@ -1,8 +0,0 @@ -libfreestanding = static_library( - 'freestanding', - sources: [ - 'entry.c', - 'vdso.c', - ], - include_directories: common_includes, -) diff --git a/lib/freestanding/vdso.c b/lib/freestanding/vdso.c deleted file mode 100644 index dd71ef6..0000000 --- a/lib/freestanding/vdso.c +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static uint8_t vdso_symbol_bind(uint8_t info) { - return ELF64_ST_BIND(info); -} - -static uint8_t vdso_symbol_type(uint8_t info) { - return ELF64_ST_TYPE(info); -} - -struct vdso_info { - uintptr_t base; - const char* strings; - const struct elf64_sym* symbols; - size_t symbol_count; -}; - -static bool vdso_info_init(struct vdso_info* info) { - const uintptr_t base = getauxval(AT_SYSINFO_EHDR); - if (!base) - return false; - - const struct elf64_ehdr* ehdr = (const void*)base; - if (ehdr->e_ident[EI_MAG0] != ELF_MAG[0] || ehdr->e_ident[EI_MAG1] != ELF_MAG[1] || - ehdr->e_ident[EI_MAG2] != ELF_MAG[2] || ehdr->e_ident[EI_MAG3] != ELF_MAG[3] || - ehdr->e_ident[EI_CLASS] != ELFCLASS64 || ehdr->e_ident[EI_DATA] != ELFDATA2LSB || - ehdr->e_machine != ELF_ARCH_MACHINE) - return false; - - const struct elf64_dyn* dynamic = nullptr; - for (size_t i = 0; i < ehdr->e_phnum; i++) { - const struct elf64_phdr* phdr = (const void*)(base + ehdr->e_phoff + (i * ehdr->e_phentsize)); - if (phdr->p_type == PT_DYNAMIC) { - dynamic = (const void*)(base + phdr->p_vaddr); - break; - } - } - if (!dynamic) - return false; - - const char* strings = nullptr; - const struct elf64_sym* symbols = nullptr; - const struct elf_hash* hash = nullptr; - - for (const struct elf64_dyn* entry = dynamic; entry->d_tag != DT_NULL; entry++) { - switch (entry->d_tag) { - case DT_STRTAB: - strings = (const void*)(base + entry->d_un.d_ptr); - break; - case DT_SYMTAB: - symbols = (const void*)(base + entry->d_un.d_ptr); - break; - case DT_HASH: - hash = (const void*)(base + entry->d_un.d_ptr); - break; - default: - break; - } - } - - if (!strings || !symbols || !hash) - return false; - - *info = (struct vdso_info){ - .base = base, - .strings = strings, - .symbols = symbols, - .symbol_count = hash->n_chain, - }; - return true; -} - -static void* vdso_lookup(const char* name) { - struct vdso_info info; - if (!vdso_info_init(&info)) - return nullptr; - - for (size_t i = 0; i < info.symbol_count; i++) { - const struct elf64_sym* symbol = &info.symbols[i]; - if (vdso_symbol_bind(symbol->st_info) != STB_GLOBAL || vdso_symbol_type(symbol->st_info) != STT_FUNC) - continue; - - const char* symbol_name = info.strings + symbol->st_name; - const char* lhs = symbol_name; - const char* rhs = name; - while (*lhs && *lhs == *rhs) { - lhs++; - rhs++; - } - if (*lhs == 0 && *rhs == 0) - return (void*)(info.base + symbol->st_value); - } - - return nullptr; -} - -#define VDSO_IFUNC(name) \ - static typeof(name)* resolve_##name(void) { \ - return (typeof(name)*)vdso_lookup("__vdso_" #name); \ - } \ - typeof(name) name __attribute__((ifunc("resolve_" #name))); - -VDSO_IFUNC(zn_archctl); -VDSO_IFUNC(zn_channel_create); -VDSO_IFUNC(zn_channel_write); -VDSO_IFUNC(zn_channel_read); -VDSO_IFUNC(zn_futex_wait); -VDSO_IFUNC(zn_futex_wake); -VDSO_IFUNC(zn_handle_validate); -VDSO_IFUNC(zn_handle_drop); -VDSO_IFUNC(zn_handle_clone); -VDSO_IFUNC(zn_vmo_create); -VDSO_IFUNC(zn_vmo_create_phys); -VDSO_IFUNC(zn_vmo_map); -VDSO_IFUNC(zn_vas_create); -VDSO_IFUNC(zn_ns_create); -VDSO_IFUNC(zn_ns_move); -VDSO_IFUNC(zn_random_get); -VDSO_IFUNC(zn_random_entropy); -VDSO_IFUNC(zn_status_to_string); -VDSO_IFUNC(zn_log); -VDSO_IFUNC(zn_page_size); -VDSO_IFUNC(zn_powerctl); -VDSO_IFUNC(zn_time); -VDSO_IFUNC(zn_thread_create); -VDSO_IFUNC(zn_thread_start); -VDSO_IFUNC(zn_thread_exit); diff --git a/lib/meson.build b/lib/meson.build index b3936d3..43fe8cc 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -1,3 +1 @@ -subdir('freestanding') - subdir('device')