Refactor error types and error reporting

This commit is contained in:
Drew Galbraith 2023-06-07 08:50:08 -07:00
parent 81b925eea0
commit a5c4d40575
8 changed files with 137 additions and 147 deletions

View File

@ -12,17 +12,17 @@ void check(uint64_t code) {
switch (code) { switch (code) {
case Z_OK: case Z_OK:
return; return;
case ZE_NOT_FOUND: case Z_ERR_UNIMPLEMENTED:
dbgln("crash: NOT_FOUND");
break;
case ZE_INVALID:
dbgln("crash: INVALID");
break;
case ZE_DENIED:
dbgln("crash: DENIED");
break;
case ZE_UNIMPLEMENTED:
dbgln("crash: UNIMPLEMENTED"); dbgln("crash: UNIMPLEMENTED");
case Z_ERR_CAP_NOT_FOUND:
dbgln("crash: missing capability");
break;
case Z_ERR_CAP_TYPE:
dbgln("crash: capability of the wrong type");
break;
case Z_ERR_CAP_DENIED:
dbgln("crash: capability permissions error");
break;
default: default:
dbgln("Unhandled code"); dbgln("Unhandled code");
break; break;

View File

@ -2,6 +2,20 @@
#include <stdarg.h> #include <stdarg.h>
#include "include/zerrors.h"
void dbg(const char* fmt, ...); void dbg(const char* fmt, ...);
void dbgln(const char* str, ...); void dbgln(const char* str, ...);
void panic(const char* str, ...); void panic(const char* str, ...);
#define RET_ERR(expr) \
{ \
z_err_t _tmp_err = expr; \
if (_tmp_err != Z_OK) { \
return _tmp_err; \
} \
}
#define UNREACHABLE \
panic("Unreachable %s, %s", __FILE__, __LINE__); \
__builtin_unreachable();

View File

@ -2,6 +2,8 @@
#include <stdint.h> #include <stdint.h>
#include "zerrors.h"
#define Z_INVALID 0x0 #define Z_INVALID 0x0
#define ZC_WRITE 0x01 #define ZC_WRITE 0x01
@ -43,35 +45,35 @@
void ZProcessExit(uint64_t code); void ZProcessExit(uint64_t code);
[[nodiscard]] uint64_t ZProcessSpawn(uint64_t proc_cap, uint64_t bootstrap_cap, [[nodiscard]] z_err_t ZProcessSpawn(uint64_t proc_cap, uint64_t bootstrap_cap,
uint64_t* new_proc_cap, uint64_t* new_proc_cap,
uint64_t* new_vmas_cap, uint64_t* new_vmas_cap,
uint64_t* new_bootstrap_cap); uint64_t* new_bootstrap_cap);
// UNUSED for now, I think we can get away with just starting a thread. // UNUSED for now, I think we can get away with just starting a thread.
[[nodiscard]] uint64_t ZProcessStart(uint64_t proc_cap, uint64_t thread_cap, [[nodiscard]] z_err_t ZProcessStart(uint64_t proc_cap, uint64_t thread_cap,
uint64_t entry, uint64_t arg1, uint64_t entry, uint64_t arg1,
uint64_t arg2); uint64_t arg2);
[[nodiscard]] uint64_t ZThreadCreate(uint64_t proc_cap, uint64_t* thread_cap); [[nodiscard]] z_err_t ZThreadCreate(uint64_t proc_cap, uint64_t* thread_cap);
[[nodiscard]] uint64_t ZThreadStart(uint64_t thread_cap, uint64_t entry, [[nodiscard]] z_err_t ZThreadStart(uint64_t thread_cap, uint64_t entry,
uint64_t arg1, uint64_t arg2); uint64_t arg1, uint64_t arg2);
void ZThreadExit(); void ZThreadExit();
[[nodiscard]] uint64_t ZAddressSpaceMap(uint64_t vmas_cap, uint64_t vmas_offset, [[nodiscard]] z_err_t ZAddressSpaceMap(uint64_t vmas_cap, uint64_t vmas_offset,
uint64_t vmmo_cap, uint64_t* vaddr); uint64_t vmmo_cap, uint64_t* vaddr);
[[nodiscard]] uint64_t ZMemoryObjectCreate(uint64_t size, uint64_t* vmmo_cap); [[nodiscard]] z_err_t ZMemoryObjectCreate(uint64_t size, uint64_t* vmmo_cap);
[[nodiscard]] uint64_t ZChannelCreate(uint64_t* channel1, uint64_t* channel2); [[nodiscard]] z_err_t ZChannelCreate(uint64_t* channel1, uint64_t* channel2);
[[nodiscard]] uint64_t ZChannelSend(uint64_t chan_cap, uint64_t type, [[nodiscard]] z_err_t ZChannelSend(uint64_t chan_cap, uint64_t type,
uint64_t num_bytes, const uint8_t* bytes, uint64_t num_bytes, const uint8_t* bytes,
uint64_t num_caps, const uint64_t* caps); uint64_t num_caps, const uint64_t* caps);
[[nodiscard]] uint64_t ZChannelRecv(uint64_t chan_cap, uint64_t num_bytes, [[nodiscard]] z_err_t ZChannelRecv(uint64_t chan_cap, uint64_t num_bytes,
uint8_t* bytes, uint64_t num_caps, uint8_t* bytes, uint64_t num_caps,
uint64_t* caps, uint64_t* type, uint64_t* caps, uint64_t* type,
uint64_t* actual_bytes, uint64_t* actual_bytes,
uint64_t* actual_caps); uint64_t* actual_caps);
[[nodiscard]] uint64_t ZDebug(const char* message); [[nodiscard]] z_err_t ZDebug(const char* message);

View File

@ -1,8 +1,16 @@
#pragma once #pragma once
#include <stdint.h>
#define Z_OK 0x0 #define Z_OK 0x0
#define ZE_NOT_FOUND 0x1 #define Z_ERR_NOT_FOUND 0x1
#define ZE_INVALID 0x2 #define Z_ERR_INVALID 0x2
#define ZE_DENIED 0x4 #define Z_ERR_DENIED 0x3
#define ZE_UNIMPLEMENTED 0x8 #define Z_ERR_UNIMPLEMENTED 0x4
#define ZE_BUFF_SIZE 0x10 #define Z_ERR_BUFF_SIZE 0x05
#define Z_ERR_CAP_NOT_FOUND 0x100
#define Z_ERR_CAP_TYPE 0x101
#define Z_ERR_CAP_DENIED 0x102
typedef uint64_t z_err_t;

View File

@ -10,18 +10,18 @@ Pair<RefPtr<Channel>, RefPtr<Channel>> Channel::CreateChannelPair() {
return {c1, c2}; return {c1, c2};
} }
uint64_t Channel::Write(const ZMessage& msg) { z_err_t Channel::Write(const ZMessage& msg) {
return peer_->EnqueueMessage(msg); return peer_->EnqueueMessage(msg);
} }
uint64_t Channel::Read(ZMessage& msg) { z_err_t Channel::Read(ZMessage& msg) {
if (pending_messages_.size() == 0) { if (pending_messages_.size() == 0) {
dbgln("Unimplemented add blocking."); dbgln("Unimplemented add blocking.");
return ZE_UNIMPLEMENTED; return Z_ERR_UNIMPLEMENTED;
} }
Message next_msg = pending_messages_.PeekFront(); Message next_msg = pending_messages_.PeekFront();
if (next_msg.num_bytes > msg.num_bytes) { if (next_msg.num_bytes > msg.num_bytes) {
return ZE_BUFF_SIZE; return Z_ERR_BUFF_SIZE;
} }
msg.type = next_msg.type; msg.type = next_msg.type;
@ -37,15 +37,15 @@ uint64_t Channel::Read(ZMessage& msg) {
return Z_OK; return Z_OK;
} }
uint64_t Channel::EnqueueMessage(const ZMessage& msg) { z_err_t Channel::EnqueueMessage(const ZMessage& msg) {
if (msg.num_caps > 0) { if (msg.num_caps > 0) {
dbgln("Unimplemented passing caps on channel"); dbgln("Unimplemented passing caps on channel");
return ZE_UNIMPLEMENTED; return Z_ERR_UNIMPLEMENTED;
} }
if (msg.num_bytes > 0x1000) { if (msg.num_bytes > 0x1000) {
dbgln("Large message size unimplemented: %x", msg.num_bytes); dbgln("Large message size unimplemented: %x", msg.num_bytes);
return ZE_INVALID; return Z_ERR_INVALID;
} }
Message message{ Message message{

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "capability/capability.h" #include "capability/capability.h"
#include "include/zerrors.h"
#include "lib/linked_list.h" #include "lib/linked_list.h"
#include "lib/pair.h" #include "lib/pair.h"
#include "lib/ref_ptr.h" #include "lib/ref_ptr.h"
@ -13,8 +14,8 @@ class Channel : public KernelObject {
RefPtr<Channel> peer() { return peer_; } RefPtr<Channel> peer() { return peer_; }
uint64_t Write(const ZMessage& msg); z_err_t Write(const ZMessage& msg);
uint64_t Read(ZMessage& msg); z_err_t Read(ZMessage& msg);
private: private:
// FIXME: We will likely never close the channel based on this // FIXME: We will likely never close the channel based on this
@ -36,5 +37,5 @@ class Channel : public KernelObject {
Channel() {} Channel() {}
void SetPeer(const RefPtr<Channel>& peer) { peer_ = peer; } void SetPeer(const RefPtr<Channel>& peer) { peer_ = peer; }
uint64_t EnqueueMessage(const ZMessage& msg); z_err_t EnqueueMessage(const ZMessage& msg);
}; };

View File

@ -57,18 +57,25 @@ void InitSyscall() {
SetMSR(LSTAR, reinterpret_cast<uint64_t>(syscall_enter)); SetMSR(LSTAR, reinterpret_cast<uint64_t>(syscall_enter));
} }
uint64_t ProcessSpawn(ZProcessSpawnReq* req, ZProcessSpawnResp* resp) { z_err_t ValidateCap(const RefPtr<Capability>& cap, Capability::Type type,
uint64_t permissions) {
if (!cap) {
return Z_ERR_CAP_NOT_FOUND;
}
if (!cap->CheckType(type)) {
return Z_ERR_CAP_TYPE;
}
if (!cap->HasPermissions(permissions)) {
return Z_ERR_CAP_DENIED;
}
return Z_OK;
}
z_err_t ProcessSpawn(ZProcessSpawnReq* req, ZProcessSpawnResp* resp) {
auto& curr_proc = gScheduler->CurrentProcess(); auto& curr_proc = gScheduler->CurrentProcess();
auto cap = curr_proc.GetCapability(req->proc_cap); auto cap = curr_proc.GetCapability(req->proc_cap);
if (!cap) { RET_ERR(ValidateCap(cap, Capability::PROCESS, ZC_PROC_SPAWN_PROC));
return ZE_NOT_FOUND;
}
if (!cap->CheckType(Capability::PROCESS)) {
return ZE_INVALID;
}
if (!cap->HasPermissions(ZC_PROC_SPAWN_PROC)) {
return ZE_DENIED;
}
RefPtr<Process> proc = Process::Create(); RefPtr<Process> proc = Process::Create();
gProcMan->InsertProcess(proc); gProcMan->InsertProcess(proc);
@ -78,7 +85,7 @@ uint64_t ProcessSpawn(ZProcessSpawnReq* req, ZProcessSpawnResp* resp) {
if (req->bootstrap_cap != 0) { if (req->bootstrap_cap != 0) {
auto cap = curr_proc.ReleaseCapability(req->bootstrap_cap); auto cap = curr_proc.ReleaseCapability(req->bootstrap_cap);
if (!cap) { if (!cap) {
return ZE_NOT_FOUND; return Z_ERR_CAP_NOT_FOUND;
} }
// FIXME: Check permissions. // FIXME: Check permissions.
resp->bootstrap_cap = proc->AddCapability(cap); resp->bootstrap_cap = proc->AddCapability(cap);
@ -87,19 +94,10 @@ uint64_t ProcessSpawn(ZProcessSpawnReq* req, ZProcessSpawnResp* resp) {
return Z_OK; return Z_OK;
} }
uint64_t ThreadCreate(ZThreadCreateReq* req, ZThreadCreateResp* resp) { z_err_t ThreadCreate(ZThreadCreateReq* req, ZThreadCreateResp* resp) {
auto& curr_proc = gScheduler->CurrentProcess(); auto& curr_proc = gScheduler->CurrentProcess();
auto cap = curr_proc.GetCapability(req->proc_cap); auto cap = curr_proc.GetCapability(req->proc_cap);
if (!cap) { RET_ERR(ValidateCap(cap, Capability::PROCESS, ZC_PROC_SPAWN_THREAD));
return ZE_NOT_FOUND;
}
if (!cap->CheckType(Capability::PROCESS)) {
return ZE_INVALID;
}
if (!cap->HasPermissions(ZC_PROC_SPAWN_THREAD)) {
return ZE_DENIED;
}
auto parent_proc = cap->obj<Process>(); auto parent_proc = cap->obj<Process>();
auto thread = parent_proc->CreateThread(); auto thread = parent_proc->CreateThread();
@ -108,19 +106,10 @@ uint64_t ThreadCreate(ZThreadCreateReq* req, ZThreadCreateResp* resp) {
return Z_OK; return Z_OK;
} }
uint64_t ThreadStart(ZThreadStartReq* req) { z_err_t ThreadStart(ZThreadStartReq* req) {
auto& curr_proc = gScheduler->CurrentProcess(); auto& curr_proc = gScheduler->CurrentProcess();
auto cap = curr_proc.GetCapability(req->thread_cap); auto cap = curr_proc.GetCapability(req->thread_cap);
if (!cap) { RET_ERR(ValidateCap(cap, Capability::THREAD, ZC_WRITE));
return ZE_NOT_FOUND;
}
if (!cap->CheckType(Capability::THREAD)) {
return ZE_INVALID;
}
if (!cap->HasPermissions(ZC_WRITE)) {
return ZE_DENIED;
}
auto thread = cap->obj<Thread>(); auto thread = cap->obj<Thread>();
// FIXME: validate entry point is in user space. // FIXME: validate entry point is in user space.
@ -128,21 +117,13 @@ uint64_t ThreadStart(ZThreadStartReq* req) {
return Z_OK; return Z_OK;
} }
uint64_t AddressSpaceMap(ZAddressSpaceMapReq* req, ZAddressSpaceMapResp* resp) { z_err_t AddressSpaceMap(ZAddressSpaceMapReq* req, ZAddressSpaceMapResp* resp) {
auto& curr_proc = gScheduler->CurrentProcess(); auto& curr_proc = gScheduler->CurrentProcess();
auto vmas_cap = curr_proc.GetCapability(req->vmas_cap); auto vmas_cap = curr_proc.GetCapability(req->vmas_cap);
auto vmmo_cap = curr_proc.GetCapability(req->vmmo_cap); auto vmmo_cap = curr_proc.GetCapability(req->vmmo_cap);
if (!vmas_cap || !vmmo_cap) { RET_ERR(ValidateCap(vmas_cap, Capability::ADDRESS_SPACE, ZC_WRITE));
return ZE_NOT_FOUND; RET_ERR(ValidateCap(vmmo_cap, Capability::MEMORY_OBJECT, ZC_WRITE));
}
if (!vmas_cap->CheckType(Capability::ADDRESS_SPACE) ||
!vmmo_cap->CheckType(Capability::MEMORY_OBJECT)) {
return ZE_INVALID;
}
if (!vmas_cap->HasPermissions(ZC_WRITE) ||
!vmmo_cap->HasPermissions(ZC_WRITE)) {
return ZE_DENIED;
}
auto vmas = vmas_cap->obj<AddressSpace>(); auto vmas = vmas_cap->obj<AddressSpace>();
auto vmmo = vmmo_cap->obj<MemoryObject>(); auto vmmo = vmmo_cap->obj<MemoryObject>();
// FIXME: Validation necessary. // FIXME: Validation necessary.
@ -155,7 +136,7 @@ uint64_t AddressSpaceMap(ZAddressSpaceMapReq* req, ZAddressSpaceMapResp* resp) {
return Z_OK; return Z_OK;
} }
uint64_t MemoryObjectCreate(ZMemoryObjectCreateReq* req, z_err_t MemoryObjectCreate(ZMemoryObjectCreateReq* req,
ZMemoryObjectCreateResp* resp) { ZMemoryObjectCreateResp* resp) {
auto& curr_proc = gScheduler->CurrentProcess(); auto& curr_proc = gScheduler->CurrentProcess();
resp->vmmo_cap = resp->vmmo_cap =
@ -163,7 +144,7 @@ uint64_t MemoryObjectCreate(ZMemoryObjectCreateReq* req,
return Z_OK; return Z_OK;
} }
uint64_t ChannelCreate(ZChannelCreateResp* resp) { z_err_t ChannelCreate(ZChannelCreateResp* resp) {
auto& proc = gScheduler->CurrentProcess(); auto& proc = gScheduler->CurrentProcess();
auto chan_pair = Channel::CreateChannelPair(); auto chan_pair = Channel::CreateChannelPair();
resp->chan_cap1 = proc.AddCapability(chan_pair.first()); resp->chan_cap1 = proc.AddCapability(chan_pair.first());
@ -171,41 +152,27 @@ uint64_t ChannelCreate(ZChannelCreateResp* resp) {
return Z_OK; return Z_OK;
} }
uint64_t ChannelSend(ZChannelSendReq* req) { z_err_t ChannelSend(ZChannelSendReq* req) {
auto& proc = gScheduler->CurrentProcess(); auto& proc = gScheduler->CurrentProcess();
auto chan_cap = proc.GetCapability(req->chan_cap); auto chan_cap = proc.GetCapability(req->chan_cap);
if (!chan_cap) { RET_ERR(ValidateCap(chan_cap, Capability::CHANNEL, ZC_WRITE));
return ZE_NOT_FOUND;
}
if (!chan_cap->CheckType(Capability::CHANNEL)) {
return ZE_INVALID;
}
if (!chan_cap->HasPermissions(ZC_WRITE)) {
return ZE_DENIED;
}
auto chan = chan_cap->obj<Channel>(); auto chan = chan_cap->obj<Channel>();
chan->Write(req->message); chan->Write(req->message);
return Z_OK; return Z_OK;
} }
uint64_t ChannelRecv(ZChannelRecvReq* req) { z_err_t ChannelRecv(ZChannelRecvReq* req) {
auto& proc = gScheduler->CurrentProcess(); auto& proc = gScheduler->CurrentProcess();
auto chan_cap = proc.GetCapability(req->chan_cap); auto chan_cap = proc.GetCapability(req->chan_cap);
if (!chan_cap) { RET_ERR(ValidateCap(chan_cap, Capability::CHANNEL, ZC_READ));
return ZE_NOT_FOUND;
}
if (!chan_cap->CheckType(Capability::CHANNEL)) {
return ZE_INVALID;
}
if (!chan_cap->HasPermissions(ZC_READ)) {
return ZE_DENIED;
}
auto chan = chan_cap->obj<Channel>(); auto chan = chan_cap->obj<Channel>();
chan->Read(req->message); chan->Read(req->message);
return Z_OK; return Z_OK;
} }
extern "C" uint64_t SyscallHandler(uint64_t call_id, void* req, void* resp) { extern "C" z_err_t SyscallHandler(uint64_t call_id, void* req, void* resp) {
Thread& thread = gScheduler->CurrentThread(); Thread& thread = gScheduler->CurrentThread();
switch (call_id) { switch (call_id) {
case Z_PROCESS_EXIT: case Z_PROCESS_EXIT:
@ -247,5 +214,5 @@ extern "C" uint64_t SyscallHandler(uint64_t call_id, void* req, void* resp) {
default: default:
panic("Unhandled syscall number: %x", call_id); panic("Unhandled syscall number: %x", call_id);
} }
return 1; UNREACHABLE
} }

View File

@ -4,8 +4,8 @@
#include "usr/zcall_internal.h" #include "usr/zcall_internal.h"
uint64_t SysCall2(uint64_t number, const void* first, const void* second) { z_err_t SysCall2(uint64_t number, const void* first, const void* second) {
uint64_t return_code; z_err_t return_code;
asm("syscall" asm("syscall"
: "=a"(return_code) : "=a"(return_code)
: "D"(number), "S"(first), "d"(second) : "D"(number), "S"(first), "d"(second)
@ -13,9 +13,9 @@ uint64_t SysCall2(uint64_t number, const void* first, const void* second) {
return return_code; return return_code;
} }
uint64_t SysCall0(uint64_t number) { return SysCall2(number, 0, 0); } z_err_t SysCall0(uint64_t number) { return SysCall2(number, 0, 0); }
uint64_t SysCall1(uint64_t number, const void* first) { z_err_t SysCall1(uint64_t number, const void* first) {
return SysCall2(number, first, 0); return SysCall2(number, first, 0);
} }
@ -23,7 +23,7 @@ void ZProcessExit(uint64_t code) {
SysCall1(Z_PROCESS_EXIT, reinterpret_cast<void*>(code)); SysCall1(Z_PROCESS_EXIT, reinterpret_cast<void*>(code));
} }
uint64_t ZProcessSpawn(uint64_t proc_cap, uint64_t bootstrap_cap, z_err_t ZProcessSpawn(uint64_t proc_cap, uint64_t bootstrap_cap,
uint64_t* new_proc_cap, uint64_t* new_vmas_cap, uint64_t* new_proc_cap, uint64_t* new_vmas_cap,
uint64_t* new_bootstrap_cap) { uint64_t* new_bootstrap_cap) {
ZProcessSpawnReq req{ ZProcessSpawnReq req{
@ -31,24 +31,24 @@ uint64_t ZProcessSpawn(uint64_t proc_cap, uint64_t bootstrap_cap,
.bootstrap_cap = bootstrap_cap, .bootstrap_cap = bootstrap_cap,
}; };
ZProcessSpawnResp resp; ZProcessSpawnResp resp;
uint64_t ret = SysCall2(Z_PROCESS_SPAWN, &req, &resp); z_err_t ret = SysCall2(Z_PROCESS_SPAWN, &req, &resp);
*new_proc_cap = resp.proc_cap; *new_proc_cap = resp.proc_cap;
*new_vmas_cap = resp.vmas_cap; *new_vmas_cap = resp.vmas_cap;
*new_bootstrap_cap = resp.bootstrap_cap; *new_bootstrap_cap = resp.bootstrap_cap;
return ret; return ret;
} }
uint64_t ZThreadCreate(uint64_t proc_cap, uint64_t* thread_cap) { z_err_t ZThreadCreate(uint64_t proc_cap, uint64_t* thread_cap) {
ZThreadCreateReq req{ ZThreadCreateReq req{
.proc_cap = proc_cap, .proc_cap = proc_cap,
}; };
ZThreadCreateResp resp; ZThreadCreateResp resp;
uint64_t ret = SysCall2(Z_THREAD_CREATE, &req, &resp); z_err_t ret = SysCall2(Z_THREAD_CREATE, &req, &resp);
*thread_cap = resp.thread_cap; *thread_cap = resp.thread_cap;
return ret; return ret;
} }
uint64_t ZThreadStart(uint64_t thread_cap, uint64_t entry, uint64_t arg1, z_err_t ZThreadStart(uint64_t thread_cap, uint64_t entry, uint64_t arg1,
uint64_t arg2) { uint64_t arg2) {
ZThreadStartReq req{ ZThreadStartReq req{
.thread_cap = thread_cap, .thread_cap = thread_cap,
@ -61,7 +61,7 @@ uint64_t ZThreadStart(uint64_t thread_cap, uint64_t entry, uint64_t arg1,
void ZThreadExit() { SysCall0(Z_THREAD_EXIT); } void ZThreadExit() { SysCall0(Z_THREAD_EXIT); }
uint64_t ZAddressSpaceMap(uint64_t vmas_cap, uint64_t vmas_offset, z_err_t ZAddressSpaceMap(uint64_t vmas_cap, uint64_t vmas_offset,
uint64_t vmmo_cap, uint64_t* vaddr) { uint64_t vmmo_cap, uint64_t* vaddr) {
ZAddressSpaceMapReq req{ ZAddressSpaceMapReq req{
.vmas_cap = vmas_cap, .vmas_cap = vmas_cap,
@ -69,29 +69,29 @@ uint64_t ZAddressSpaceMap(uint64_t vmas_cap, uint64_t vmas_offset,
.vmmo_cap = vmmo_cap, .vmmo_cap = vmmo_cap,
}; };
ZAddressSpaceMapResp resp; ZAddressSpaceMapResp resp;
uint64_t ret = SysCall2(Z_ADDRESS_SPACE_MAP, &req, &resp); z_err_t ret = SysCall2(Z_ADDRESS_SPACE_MAP, &req, &resp);
*vaddr = resp.vaddr; *vaddr = resp.vaddr;
return ret; return ret;
} }
uint64_t ZMemoryObjectCreate(uint64_t size, uint64_t* vmmo_cap) { z_err_t ZMemoryObjectCreate(uint64_t size, uint64_t* vmmo_cap) {
ZMemoryObjectCreateReq req{ ZMemoryObjectCreateReq req{
.size = size, .size = size,
}; };
ZMemoryObjectCreateResp resp; ZMemoryObjectCreateResp resp;
uint64_t ret = SysCall2(Z_MEMORY_OBJECT_CREATE, &req, &resp); z_err_t ret = SysCall2(Z_MEMORY_OBJECT_CREATE, &req, &resp);
*vmmo_cap = resp.vmmo_cap; *vmmo_cap = resp.vmmo_cap;
return ret; return ret;
} }
uint64_t ZChannelCreate(uint64_t* channel1, uint64_t* channel2) { z_err_t ZChannelCreate(uint64_t* channel1, uint64_t* channel2) {
ZChannelCreateResp resp; ZChannelCreateResp resp;
uint64_t ret = SysCall2(Z_CHANNEL_CREATE, 0, &resp); z_err_t ret = SysCall2(Z_CHANNEL_CREATE, 0, &resp);
*channel1 = resp.chan_cap1; *channel1 = resp.chan_cap1;
*channel2 = resp.chan_cap2; *channel2 = resp.chan_cap2;
return ret; return ret;
} }
uint64_t ZChannelSend(uint64_t chan_cap, uint64_t type, uint64_t num_bytes, z_err_t ZChannelSend(uint64_t chan_cap, uint64_t type, uint64_t num_bytes,
const uint8_t* bytes, uint64_t num_caps, const uint8_t* bytes, uint64_t num_caps,
const uint64_t* caps) { const uint64_t* caps) {
ZChannelSendReq req{ ZChannelSendReq req{
@ -108,7 +108,7 @@ uint64_t ZChannelSend(uint64_t chan_cap, uint64_t type, uint64_t num_bytes,
return SysCall1(Z_CHANNEL_SEND, &req); return SysCall1(Z_CHANNEL_SEND, &req);
} }
uint64_t ZChannelRecv(uint64_t chan_cap, uint64_t num_bytes, uint8_t* bytes, z_err_t ZChannelRecv(uint64_t chan_cap, uint64_t num_bytes, uint8_t* bytes,
uint64_t num_caps, uint64_t* caps, uint64_t* type, uint64_t num_caps, uint64_t* caps, uint64_t* type,
uint64_t* actual_bytes, uint64_t* actual_caps) { uint64_t* actual_bytes, uint64_t* actual_caps) {
ZChannelRecvReq req{ ZChannelRecvReq req{
@ -122,13 +122,11 @@ uint64_t ZChannelRecv(uint64_t chan_cap, uint64_t num_bytes, uint8_t* bytes,
.caps = caps, .caps = caps,
}, },
}; };
uint64_t ret = SysCall1(Z_CHANNEL_RECV, &req); z_err_t ret = SysCall1(Z_CHANNEL_RECV, &req);
*type = req.message.type; *type = req.message.type;
*actual_bytes = req.message.num_bytes; *actual_bytes = req.message.num_bytes;
*actual_caps = req.message.num_caps; *actual_caps = req.message.num_caps;
return ret; return ret;
} }
uint64_t ZDebug(const char* message) { z_err_t ZDebug(const char* message) { return SysCall1(Z_DEBUG_PRINT, message); }
return SysCall1(Z_DEBUG_PRINT, message);
}