This commit is contained in:
2026-09-15 22:21:27 +02:00
parent 9e5ed517bc
commit 09ab2f1a83
24 changed files with 356 additions and 357 deletions
+4 -1
View File
@@ -4,6 +4,7 @@
#define ZINNIA_ARCHCTL_H
#include <zinnia/status.h>
#include <zinnia/syscall.h>
#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
}
+25 -5
View File
@@ -5,6 +5,7 @@
#include <zinnia/handle.h>
#include <zinnia/status.h>
#include <zinnia/syscall.h>
#include <stddef.h>
#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
}
+7 -2
View File
@@ -4,6 +4,7 @@
#define ZINNIA_FUTEX_H
#include <zinnia/status.h>
#include <zinnia/syscall.h>
#include <stdint.h>
#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
}
+10 -3
View File
@@ -5,6 +5,7 @@
#include <zinnia/rights.h>
#include <zinnia/status.h>
#include <zinnia/syscall.h>
#include <stdint.h>
#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
}
+13 -5
View File
@@ -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
}
+6 -2
View File
@@ -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
}
+1 -3
View File
@@ -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);
+16
View File
@@ -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
-2
View File
@@ -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
+236
View File
@@ -0,0 +1,236 @@
// SPDX-License-Identifier: MIT
#ifndef ZINNIA_SYSCALL_H
#define ZINNIA_SYSCALL_H
#include <zinnia/status.h>
#include <zinnia/syscall_numbers.h>
#include <stdint.h>
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
+38
View File
@@ -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
+246
View File
@@ -0,0 +1,246 @@
#pragma once
#include <zinnia/status.h>
#include <kernel/syscall_numbers.h>
#include <stdint.h>
#ifdef __x86_64__
typedef uint64_t zn_arg_t;
#elif defined(__aarch64__)
typedef uint64_t zn_arg_t;
#elif defined(__riscv) && (__riscv_xlen == 64)
typedef uint64_t zn_arg_t;
#elif defined(__loongarch64)
typedef uint64_t zn_arg_t;
#else
#error "Unsupported architecture!"
#endif
#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
// These symbols should not be used in the kernel, ever.
#ifdef IN_VDSO
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
-4
View File
@@ -4,7 +4,6 @@
#define ZINNIA_SYSTEM_H
#include <zinnia/status.h>
#include <stdint.h>
#include <string.h>
#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