Initial commit
This commit is contained in:
@@ -0,0 +1 @@
|
||||
subdir('zinnia')
|
||||
@@ -0,0 +1,28 @@
|
||||
#include <zinnia/channel.h>
|
||||
#include <zinnia/syscall_numbers.h>
|
||||
#include "syscall_stubs.h"
|
||||
|
||||
zn_status_t zn_channel_create(enum zn_channel_flags flags, zn_handle_t* endpoint0, zn_handle_t* endpoint1) {
|
||||
return syscall3(ZN_SYSCALL_CHANNEL_CREATE, (arg_t)flags, (arg_t)endpoint0, (arg_t)endpoint1);
|
||||
}
|
||||
|
||||
zn_status_t zn_channel_open(
|
||||
zn_handle_t channel,
|
||||
size_t num_handles,
|
||||
size_t num_bytes,
|
||||
zn_handle_t** out_handle_buf,
|
||||
void** out_data_buf
|
||||
) {
|
||||
return syscall5(
|
||||
ZN_SYSCALL_CHANNEL_OPEN,
|
||||
(arg_t)channel,
|
||||
(arg_t)num_handles,
|
||||
(arg_t)num_bytes,
|
||||
(arg_t)out_handle_buf,
|
||||
(arg_t)out_data_buf
|
||||
);
|
||||
}
|
||||
|
||||
zn_status_t zn_channel_write(zn_handle_t channel) {
|
||||
return syscall1(ZN_SYSCALL_CHANNEL_WRITE, (arg_t)channel);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <zinnia/handle.h>
|
||||
#include <zinnia/syscall_numbers.h>
|
||||
#include "syscall_stubs.h"
|
||||
|
||||
zn_status_t zn_handle_validate(zn_handle_t handle) {
|
||||
return syscall1(ZN_SYSCALL_HANDLE_VALIDATE, (arg_t)handle);
|
||||
}
|
||||
|
||||
zn_status_t zn_handle_drop(zn_handle_t handle) {
|
||||
return syscall1(ZN_SYSCALL_HANDLE_DROP, (arg_t)handle);
|
||||
}
|
||||
|
||||
zn_status_t zn_handle_clone(zn_handle_t object, zn_rights_t cloned_rights, zn_handle_t* cloned) {
|
||||
return syscall3(ZN_SYSCALL_HANDLE_CLONE, (arg_t)object, (arg_t)cloned_rights, (arg_t)cloned);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <zinnia/log.h>
|
||||
#include <zinnia/status.h>
|
||||
#include <zinnia/syscall_numbers.h>
|
||||
#include <string.h>
|
||||
#include "syscall_stubs.h"
|
||||
|
||||
void zn_log(const char* message) {
|
||||
syscall2(ZN_SYSCALL_LOG, (arg_t)message, (arg_t)strlen(message));
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
libzinnia = both_libraries(
|
||||
'zinnia',
|
||||
'channel.c',
|
||||
'handle.c',
|
||||
'log.c',
|
||||
'status.c',
|
||||
include_directories: common_includes,
|
||||
install: true,
|
||||
)
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <zinnia/status.h>
|
||||
|
||||
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 (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_BAD_ARG:
|
||||
return "One or more of the provided arguments is not valid (BAD_ARG)";
|
||||
case ZN_ERR_BAD_RANGE:
|
||||
return "Argument is outside of the range for valid values (BAD_RANGE)";
|
||||
case ZN_ERR_BAD_OBJECT:
|
||||
return "Object handle does not name a valid object (BAD_OBJECT)";
|
||||
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)";
|
||||
}
|
||||
|
||||
return "Unknown error code";
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
#pragma once
|
||||
|
||||
#include <zinnia/status.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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_SYSCALL "syscall"
|
||||
#define ASM_CLOBBER "rcx", "r11"
|
||||
typedef uint64_t arg_t;
|
||||
#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_SYSCALL "svc 0"
|
||||
#define ASM_CLOBBER
|
||||
typedef uint64_t arg_t;
|
||||
#elif defined(__riscv) && (__riscv_xlen == 64)
|
||||
#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"
|
||||
#define ASM_SYSCALL "ecall"
|
||||
#define ASM_CLOBBER
|
||||
typedef uint64_t arg_t;
|
||||
#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"
|
||||
#define ASM_SYSCALL "syscall 0"
|
||||
#define ASM_CLOBBER
|
||||
typedef uint64_t arg_t;
|
||||
#else
|
||||
#error "Unsupported architecture!"
|
||||
#endif
|
||||
|
||||
static inline zn_status_t syscall0(arg_t num) {
|
||||
register arg_t rnum asm(ASM_REG_NUM) = num;
|
||||
register arg_t value asm(ASM_REG_RET);
|
||||
asm volatile(ASM_SYSCALL : "=r"(value) : "r"(rnum) : "memory", ASM_CLOBBER);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline zn_status_t syscall1(arg_t num, arg_t a0) {
|
||||
register arg_t rnum asm(ASM_REG_NUM) = num;
|
||||
register arg_t value asm(ASM_REG_RET);
|
||||
register arg_t r0 asm(ASM_REG_A0) = a0;
|
||||
asm volatile(ASM_SYSCALL : "=r"(value) : "r"(rnum), "r"(r0) : "memory", ASM_CLOBBER);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline zn_status_t syscall2(arg_t num, arg_t a0, arg_t a1) {
|
||||
register arg_t rnum asm(ASM_REG_NUM) = num;
|
||||
register arg_t value asm(ASM_REG_RET);
|
||||
register arg_t r0 asm(ASM_REG_A0) = a0;
|
||||
register 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;
|
||||
}
|
||||
|
||||
static inline zn_status_t syscall3(arg_t num, arg_t a0, arg_t a1, arg_t a2) {
|
||||
register arg_t rnum asm(ASM_REG_NUM) = num;
|
||||
register arg_t value asm(ASM_REG_RET);
|
||||
register arg_t r0 asm(ASM_REG_A0) = a0;
|
||||
register arg_t r1 asm(ASM_REG_A1) = a1;
|
||||
register 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;
|
||||
}
|
||||
|
||||
static inline zn_status_t syscall4(arg_t num, arg_t a0, arg_t a1, arg_t a2, arg_t a3) {
|
||||
register arg_t rnum asm(ASM_REG_NUM) = num;
|
||||
register arg_t value asm(ASM_REG_RET);
|
||||
register arg_t r0 asm(ASM_REG_A0) = a0;
|
||||
register arg_t r1 asm(ASM_REG_A1) = a1;
|
||||
register arg_t r2 asm(ASM_REG_A2) = a2;
|
||||
register 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;
|
||||
}
|
||||
|
||||
static inline zn_status_t syscall5(arg_t num, arg_t a0, arg_t a1, arg_t a2, arg_t a3, arg_t a4) {
|
||||
register arg_t rnum asm(ASM_REG_NUM) = num;
|
||||
register arg_t value asm(ASM_REG_RET);
|
||||
register arg_t r0 asm(ASM_REG_A0) = a0;
|
||||
register arg_t r1 asm(ASM_REG_A1) = a1;
|
||||
register arg_t r2 asm(ASM_REG_A2) = a2;
|
||||
register arg_t r3 asm(ASM_REG_A3) = a3;
|
||||
register 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;
|
||||
}
|
||||
|
||||
static inline zn_status_t syscall6(arg_t num, arg_t a0, arg_t a1, arg_t a2, arg_t a3, arg_t a4, arg_t a5) {
|
||||
register arg_t rnum asm(ASM_REG_NUM) = num;
|
||||
register arg_t value asm(ASM_REG_RET);
|
||||
register arg_t r0 asm(ASM_REG_A0) = a0;
|
||||
register arg_t r1 asm(ASM_REG_A1) = a1;
|
||||
register arg_t r2 asm(ASM_REG_A2) = a2;
|
||||
register arg_t r3 asm(ASM_REG_A3) = a3;
|
||||
register arg_t r4 asm(ASM_REG_A4) = a4;
|
||||
register 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;
|
||||
}
|
||||
Reference in New Issue
Block a user