[zion] Move channel syscalls to new format.
This commit is contained in:
parent
1a70ce4855
commit
77bb3acfb4
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue