[zion] Move channel syscalls to new format.

This commit is contained in:
Drew Galbraith 2023-06-20 14:41:44 -07:00
parent 1a70ce4855
commit 77bb3acfb4
11 changed files with 91 additions and 123 deletions

View File

@ -7,8 +7,8 @@ class Channel {
public:
Channel() {}
void adopt_cap(uint64_t id);
uint64_t release_cap();
uint64_t cap();
z_cap_t release_cap();
z_cap_t cap();
z_err_t WriteStr(const char* msg);
z_err_t ReadStr(char* buffer, uint64_t* size);
@ -23,7 +23,7 @@ class Channel {
~Channel() {}
private:
uint64_t chan_cap_ = 0;
z_cap_t chan_cap_ = 0;
};
uint64_t CreateChannels(Channel& c1, Channel& c2);
@ -35,9 +35,10 @@ z_err_t Channel::WriteStruct(T* obj) {
template <typename T>
z_err_t Channel::ReadStructAndCap(T* obj, uint64_t* cap) {
uint64_t num_bytes, num_caps;
uint64_t ret = ZChannelRecv(chan_cap_, sizeof(T), obj, /* num_caps= */ 1, cap,
&num_bytes, &num_caps);
uint64_t num_bytes = sizeof(T);
uint64_t num_caps = 1;
uint64_t ret = ZChannelRecv(chan_cap_, &num_bytes, obj, &num_caps, cap);
if (ret != Z_OK) {
return ret;
}

View File

@ -23,33 +23,32 @@ void Channel::adopt_cap(uint64_t id) {
}
chan_cap_ = id;
}
uint64_t Channel::release_cap() {
uint64_t cap = chan_cap_;
z_cap_t Channel::release_cap() {
z_cap_t cap = chan_cap_;
chan_cap_ = 0;
return cap;
}
uint64_t Channel::cap() { return chan_cap_; }
z_cap_t Channel::cap() { return chan_cap_; }
z_err_t Channel::WriteStr(const char* msg) {
if (!chan_cap_) {
return Z_ERR_NULL;
}
return ZChannelSend(chan_cap_, strlen(msg),
reinterpret_cast<const uint8_t*>(msg), 0, 0);
return ZChannelSend(chan_cap_, strlen(msg), msg, 0, nullptr);
}
z_err_t Channel::ReadStr(char* buffer, uint64_t* size) {
if (!chan_cap_) {
return Z_ERR_NULL;
}
uint64_t num_caps;
return ZChannelRecv(chan_cap_, *size, reinterpret_cast<uint8_t*>(buffer), 0,
0, size, &num_caps);
uint64_t num_caps = 0;
return ZChannelRecv(chan_cap_, size, reinterpret_cast<uint8_t*>(buffer),
&num_caps, nullptr);
}
z_err_t CreateChannels(Channel& c1, Channel& c2) {
uint64_t chan1, chan2;
z_cap_t chan1, chan2;
z_err_t err = ZChannelCreate(&chan1, &chan2);
if (err != Z_OK) {
return err;

View File

@ -19,8 +19,8 @@ z_err_t DenaliServer::RunServer() {
while (true) {
uint64_t buff_size = kBuffSize;
uint64_t cap_size = 0;
RET_ERR(ZChannelRecv(channel_cap_, buff_size, read_buffer_, 0, nullptr,
&buff_size, &cap_size));
RET_ERR(ZChannelRecv(channel_cap_, &buff_size, read_buffer_, &cap_size,
nullptr));
if (buff_size < sizeof(uint64_t)) {
dbgln("Skipping invalid message");
continue;

View File

@ -28,6 +28,7 @@ add_executable(zion
scheduler/process_manager.cpp
scheduler/scheduler.cpp
syscall/address_space.cpp
syscall/channel.cpp
syscall/memory_object.cpp
syscall/process.cpp
syscall/syscall.cpp

View File

@ -107,14 +107,11 @@ SYS3(MemoryObjectCreateContiguous, uint64_t, size, z_cap_t*, vmmo_cap,
uint64_t*, paddr);
SYS2(TempPcieConfigObjectCreate, z_cap_t*, vmmo_cap, uint64_t*, vmmo_size);
[[nodiscard]] z_err_t ZChannelCreate(z_cap_t* channel1, z_cap_t* channel2);
[[nodiscard]] z_err_t ZChannelSend(z_cap_t chan_cap, uint64_t num_bytes,
const void* data, uint64_t num_caps,
const z_cap_t* caps);
[[nodiscard]] z_err_t ZChannelRecv(z_cap_t chan_cap, uint64_t num_bytes,
void* data, uint64_t num_caps, z_cap_t* caps,
uint64_t* actual_bytes,
uint64_t* actual_caps);
SYS2(ChannelCreate, z_cap_t*, channel1, z_cap_t*, channel2);
SYS5(ChannelSend, z_cap_t, chan_cap, uint64_t, num_bytes, const void*, data,
uint64_t, num_caps, z_cap_t*, caps);
SYS5(ChannelRecv, z_cap_t, chan_cap, uint64_t*, num_bytes, void*, data,
uint64_t*, num_caps, z_cap_t*, caps);
[[nodiscard]] z_err_t ZPortCreate(z_cap_t* port_cap);
[[nodiscard]] z_err_t ZPortSend(z_cap_t port_cap, uint64_t num_bytes,

View File

@ -49,10 +49,10 @@ const uint64_t kZionMemoryObjectCreateContiguous = 0x32;
const uint64_t kZionTempPcieConfigObjectCreate = 0x3F;
// IPC Calls
#define Z_CHANNEL_CREATE 0x40
#define Z_CHANNEL_SEND 0x41
#define Z_CHANNEL_RECV 0x42
#define Z_CHANNEL_SENDRECV 0x43
const uint64_t kZionChannelCreate = 0x40;
const uint64_t kZionChannelSend = 0x41;
const uint64_t kZionChannelRecv = 0x42;
const uint64_t kZionChannelSendRecv = 0x43;
#define Z_PORT_CREATE 0x50
#define Z_PORT_SEND 0x51

52
zion/syscall/channel.cpp Normal file
View File

@ -0,0 +1,52 @@
#include "syscall/channel.h"
#include "scheduler/scheduler.h"
#include "syscall/syscall.h"
z_err_t ChannelCreate(ZChannelCreateReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto chan_pair = Channel::CreateChannelPair();
*req->channel1 = proc.AddNewCapability(chan_pair.first(), ZC_WRITE | ZC_READ);
*req->channel2 =
proc.AddNewCapability(chan_pair.second(), ZC_WRITE | ZC_READ);
return Z_OK;
}
z_err_t ChannelSend(ZChannelSendReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto chan_cap = proc.GetCapability(req->chan_cap);
RET_ERR(ValidateCap(chan_cap, ZC_WRITE));
auto chan = chan_cap->obj<Channel>();
RET_IF_NULL(chan);
// FIXME: Get rid of this hack.
ZMessage message{
.num_bytes = req->num_bytes,
.data = const_cast<void*>(req->data),
.num_caps = req->num_caps,
.caps = req->caps,
};
return chan->Write(message);
}
z_err_t ChannelRecv(ZChannelRecvReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto chan_cap = proc.GetCapability(req->chan_cap);
RET_ERR(ValidateCap(chan_cap, ZC_READ));
auto chan = chan_cap->obj<Channel>();
RET_IF_NULL(chan);
// FIXME: Get rid of this hack.
ZMessage message{
.num_bytes = *req->num_bytes,
.data = const_cast<void*>(req->data),
.num_caps = *req->num_caps,
.caps = req->caps,
};
RET_ERR(chan->Read(message));
*req->num_bytes = message.num_bytes;
*req->num_caps = message.num_caps;
return Z_OK;
}

7
zion/syscall/channel.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
#include "include/zcall.h"
z_err_t ChannelCreate(ZChannelCreateReq* resp);
z_err_t ChannelSend(ZChannelSendReq* req);
z_err_t ChannelRecv(ZChannelRecvReq* req);

View File

@ -13,6 +13,7 @@
#include "scheduler/process_manager.h"
#include "scheduler/scheduler.h"
#include "syscall/address_space.h"
#include "syscall/channel.h"
#include "syscall/memory_object.h"
#include "syscall/process.h"
#include "syscall/thread.h"
@ -61,37 +62,6 @@ z_err_t ValidateCap(const RefPtr<Capability>& cap, uint64_t permissions) {
return Z_OK;
}
z_err_t ChannelCreate(ZChannelCreateResp* resp) {
auto& proc = gScheduler->CurrentProcess();
auto chan_pair = Channel::CreateChannelPair();
resp->chan_cap1 =
proc.AddNewCapability(chan_pair.first(), ZC_WRITE | ZC_READ);
resp->chan_cap2 =
proc.AddNewCapability(chan_pair.second(), ZC_WRITE | ZC_READ);
return Z_OK;
}
z_err_t ChannelSend(ZChannelSendReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto chan_cap = proc.GetCapability(req->chan_cap);
RET_ERR(ValidateCap(chan_cap, ZC_WRITE));
auto chan = chan_cap->obj<Channel>();
RET_IF_NULL(chan);
chan->Write(req->message);
return Z_OK;
}
z_err_t ChannelRecv(ZChannelRecvReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto chan_cap = proc.GetCapability(req->chan_cap);
RET_ERR(ValidateCap(chan_cap, ZC_READ));
auto chan = chan_cap->obj<Channel>();
RET_IF_NULL(chan);
return chan->Read(req->message);
}
z_err_t PortCreate(ZPortCreateResp* resp) {
auto& proc = gScheduler->CurrentProcess();
auto port = MakeRefCounted<Port>();
@ -175,12 +145,10 @@ extern "C" z_err_t SyscallHandler(uint64_t call_id, void* req, void* resp) {
CASE(MemoryObjectCreatePhysical);
CASE(MemoryObjectCreateContiguous);
CASE(TempPcieConfigObjectCreate);
case Z_CHANNEL_CREATE:
return ChannelCreate(reinterpret_cast<ZChannelCreateResp*>(resp));
case Z_CHANNEL_SEND:
return ChannelSend(reinterpret_cast<ZChannelSendReq*>(req));
case Z_CHANNEL_RECV:
return ChannelRecv(reinterpret_cast<ZChannelRecvReq*>(req));
// syscall/channel.h
CASE(ChannelCreate);
CASE(ChannelSend);
CASE(ChannelRecv);
case Z_PORT_CREATE:
return PortCreate(reinterpret_cast<ZPortCreateResp*>(resp));
case Z_PORT_SEND:

View File

@ -19,48 +19,6 @@ z_err_t SysCall1(uint64_t number, const void* first) {
return SysCall2(number, first, 0);
}
z_err_t ZChannelCreate(z_cap_t* channel1, z_cap_t* channel2) {
ZChannelCreateResp resp;
z_err_t ret = SysCall2(Z_CHANNEL_CREATE, 0, &resp);
*channel1 = resp.chan_cap1;
*channel2 = resp.chan_cap2;
return ret;
}
z_err_t ZChannelSend(z_cap_t chan_cap, uint64_t num_bytes, const void* data,
uint64_t num_caps, const z_cap_t* caps) {
ZChannelSendReq req{
.chan_cap = chan_cap,
.message =
{
.num_bytes = num_bytes,
.data = const_cast<void*>(data),
.num_caps = num_caps,
.caps = const_cast<z_cap_t*>(caps),
},
};
return SysCall1(Z_CHANNEL_SEND, &req);
}
z_err_t ZChannelRecv(z_cap_t chan_cap, uint64_t num_bytes, void* data,
uint64_t num_caps, z_cap_t* caps, uint64_t* actual_bytes,
uint64_t* actual_caps) {
ZChannelRecvReq req{
.chan_cap = chan_cap,
.message =
{
.num_bytes = num_bytes,
.data = data,
.num_caps = num_caps,
.caps = caps,
},
};
z_err_t ret = SysCall1(Z_CHANNEL_RECV, &req);
*actual_bytes = req.message.num_bytes;
*actual_caps = req.message.num_caps;
return ret;
}
z_err_t ZPortCreate(z_cap_t* port_cap) {
ZPortCreateResp resp;
z_err_t ret = SysCall2(Z_PORT_CREATE, 0, &resp);

View File

@ -4,11 +4,6 @@
#include "include/ztypes.h"
struct ZChannelCreateResp {
z_cap_t chan_cap1;
z_cap_t chan_cap2;
};
struct ZMessage {
uint64_t num_bytes;
void* data;
@ -17,16 +12,6 @@ struct ZMessage {
z_cap_t* caps;
};
struct ZChannelSendReq {
z_cap_t chan_cap;
ZMessage message;
};
struct ZChannelRecvReq {
z_cap_t chan_cap;
ZMessage message;
};
struct ZPortCreateResp {
z_cap_t port_cap;
};