Refactor error types and error reporting
This commit is contained in:
parent
81b925eea0
commit
a5c4d40575
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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{
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue