[zion] Move ipc syscalls to one file to prep refactor

This commit is contained in:
Drew Galbraith 2023-06-21 23:20:56 -07:00
parent c064af5fa7
commit 58df2c0ed2
12 changed files with 164 additions and 200 deletions

View File

@ -32,13 +32,10 @@ add_executable(zion
scheduler/scheduler.cpp
syscall/address_space.cpp
syscall/capability.cpp
syscall/channel.cpp
syscall/debug.cpp
syscall/endpoint.cpp
syscall/ipc.cpp
syscall/memory_object.cpp
syscall/port.cpp
syscall/process.cpp
syscall/reply_port.cpp
syscall/syscall.cpp
syscall/syscall_enter.s
syscall/thread.cpp

View File

@ -1,31 +0,0 @@
#include "syscall/channel.h"
#include "capability/capability.h"
#include "scheduler/scheduler.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 glcr::OK;
}
z_err_t ChannelSend(ZChannelSendReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto chan_cap = proc.GetCapability(req->chan_cap);
RET_ERR(ValidateCapability<Channel>(chan_cap, ZC_WRITE));
auto chan = chan_cap->obj<Channel>();
return chan->Write(req->num_bytes, req->data, req->num_caps, req->caps);
}
z_err_t ChannelRecv(ZChannelRecvReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto chan_cap = proc.GetCapability(req->chan_cap);
RET_ERR(ValidateCapability<Channel>(chan_cap, ZC_READ));
auto chan = chan_cap->obj<Channel>();
return chan->Read(req->num_bytes, req->data, req->num_caps, req->caps);
}

View File

@ -1,7 +0,0 @@
#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

@ -1,35 +0,0 @@
#include "syscall/endpoint.h"
#include "object/endpoint.h"
#include "object/reply_port.h"
#include "scheduler/scheduler.h"
glcr::ErrorCode EndpointCreate(ZEndpointCreateReq* req) {
auto& proc = gScheduler->CurrentProcess();
*req->endpoint_cap =
proc.AddNewCapability(Endpoint::Create(), ZC_READ | ZC_WRITE);
return glcr::OK;
}
glcr::ErrorCode EndpointSend(ZEndpointSendReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto endpoint_cap = proc.GetCapability(req->endpoint_cap);
ValidateCapability<Endpoint>(endpoint_cap, ZC_WRITE);
auto endpoint = endpoint_cap->obj<Endpoint>();
auto reply_port = ReplyPort::Create();
*req->reply_port_cap = proc.AddNewCapability(reply_port, ZC_READ);
uint64_t reply_port_cap_to_send = proc.AddNewCapability(reply_port, ZC_WRITE);
return endpoint->Write(req->num_bytes, req->data, reply_port_cap_to_send);
}
glcr::ErrorCode EndpointRecv(ZEndpointRecvReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto endpoint_cap = proc.GetCapability(req->endpoint_cap);
ValidateCapability<Endpoint>(endpoint_cap, ZC_READ);
auto endpoint = endpoint_cap->obj<Endpoint>();
return endpoint->Read(req->num_bytes, req->data, req->reply_port_cap);
}

View File

@ -1,11 +0,0 @@
#pragma once
#include <glacier/status/error.h>
#include "include/zcall.h"
glcr::ErrorCode EndpointCreate(ZEndpointCreateReq* req);
glcr::ErrorCode EndpointSend(ZEndpointSendReq* req);
glcr::ErrorCode EndpointRecv(ZEndpointRecvReq* req);

139
zion/syscall/ipc.cpp Normal file
View File

@ -0,0 +1,139 @@
#include "syscall/ipc.h"
#include "capability/capability.h"
#include "interrupt/interrupt.h"
#include "object/endpoint.h"
#include "object/reply_port.h"
#include "scheduler/scheduler.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 glcr::OK;
}
z_err_t ChannelSend(ZChannelSendReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto chan_cap = proc.GetCapability(req->chan_cap);
RET_ERR(ValidateCapability<Channel>(chan_cap, ZC_WRITE));
auto chan = chan_cap->obj<Channel>();
return chan->Write(req->num_bytes, req->data, req->num_caps, req->caps);
}
z_err_t ChannelRecv(ZChannelRecvReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto chan_cap = proc.GetCapability(req->chan_cap);
RET_ERR(ValidateCapability<Channel>(chan_cap, ZC_READ));
auto chan = chan_cap->obj<Channel>();
return chan->Read(req->num_bytes, req->data, req->num_caps, req->caps);
}
z_err_t PortCreate(ZPortCreateReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto port = glcr::MakeRefCounted<Port>();
*req->port_cap = proc.AddNewCapability(port, ZC_WRITE | ZC_READ);
return glcr::OK;
}
z_err_t PortSend(ZPortSendReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto port_cap = proc.GetCapability(req->port_cap);
RET_ERR(ValidateCapability<Port>(port_cap, ZC_WRITE));
auto port = port_cap->obj<Port>();
return port->Write(req->num_bytes, req->data, req->num_caps, req->caps);
}
z_err_t PortRecv(ZPortRecvReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto port_cap = proc.GetCapability(req->port_cap);
RET_ERR(ValidateCapability<Port>(port_cap, ZC_READ));
auto port = port_cap->obj<Port>();
ZMessage message{
.num_bytes = *req->num_bytes,
.data = const_cast<void*>(req->data),
.num_caps = *req->num_caps,
.caps = req->caps,
};
return port->Read(req->num_bytes, req->data, req->num_caps, req->caps);
}
z_err_t PortPoll(ZPortPollReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto port_cap = proc.GetCapability(req->port_cap);
RET_ERR(ValidateCapability<Port>(port_cap, ZC_READ));
auto port = port_cap->obj<Port>();
// FIXME: Race condition here where this call could block if the last message
// is removed between this check and the port read.
if (!port->HasMessages()) {
return glcr::EMPTY;
}
return port->Read(req->num_bytes, req->data, req->num_caps, req->caps);
}
z_err_t IrqRegister(ZIrqRegisterReq* req) {
auto& proc = gScheduler->CurrentProcess();
if (req->irq_num != Z_IRQ_PCI_BASE) {
// FIXME: Don't hardcode this nonsense.
return glcr::UNIMPLEMENTED;
}
glcr::RefPtr<Port> port = glcr::MakeRefCounted<Port>();
*req->port_cap = proc.AddNewCapability(port, ZC_READ | ZC_WRITE);
RegisterPciPort(port);
return glcr::OK;
}
glcr::ErrorCode EndpointCreate(ZEndpointCreateReq* req) {
auto& proc = gScheduler->CurrentProcess();
*req->endpoint_cap =
proc.AddNewCapability(Endpoint::Create(), ZC_READ | ZC_WRITE);
return glcr::OK;
}
glcr::ErrorCode EndpointSend(ZEndpointSendReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto endpoint_cap = proc.GetCapability(req->endpoint_cap);
ValidateCapability<Endpoint>(endpoint_cap, ZC_WRITE);
auto endpoint = endpoint_cap->obj<Endpoint>();
auto reply_port = ReplyPort::Create();
*req->reply_port_cap = proc.AddNewCapability(reply_port, ZC_READ);
uint64_t reply_port_cap_to_send = proc.AddNewCapability(reply_port, ZC_WRITE);
return endpoint->Write(req->num_bytes, req->data, reply_port_cap_to_send);
}
glcr::ErrorCode EndpointRecv(ZEndpointRecvReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto endpoint_cap = proc.GetCapability(req->endpoint_cap);
ValidateCapability<Endpoint>(endpoint_cap, ZC_READ);
auto endpoint = endpoint_cap->obj<Endpoint>();
return endpoint->Read(req->num_bytes, req->data, req->reply_port_cap);
}
glcr::ErrorCode ReplyPortSend(ZReplyPortSendReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto reply_port_cap = proc.GetCapability(req->reply_port_cap);
ValidateCapability<ReplyPort>(reply_port_cap, ZC_WRITE);
auto reply_port = reply_port_cap->obj<ReplyPort>();
return reply_port->Write(req->num_bytes, req->data, req->num_caps, req->caps);
}
glcr::ErrorCode ReplyPortRecv(ZReplyPortRecvReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto reply_port_cap = proc.GetCapability(req->reply_port_cap);
ValidateCapability<ReplyPort>(reply_port_cap, ZC_READ);
auto reply_port = reply_port_cap->obj<ReplyPort>();
return reply_port->Read(req->num_bytes, req->data, req->num_caps, req->caps);
}

22
zion/syscall/ipc.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include <glacier/status/error.h>
#include "include/zcall.h"
glcr::ErrorCode ChannelCreate(ZChannelCreateReq* resp);
glcr::ErrorCode ChannelSend(ZChannelSendReq* req);
glcr::ErrorCode ChannelRecv(ZChannelRecvReq* req);
glcr::ErrorCode PortCreate(ZPortCreateReq* req);
glcr::ErrorCode PortSend(ZPortSendReq* req);
glcr::ErrorCode PortRecv(ZPortRecvReq* req);
glcr::ErrorCode PortPoll(ZPortPollReq* req);
glcr::ErrorCode IrqRegister(ZIrqRegisterReq* req);
glcr::ErrorCode EndpointCreate(ZEndpointCreateReq* req);
glcr::ErrorCode EndpointSend(ZEndpointSendReq* req);
glcr::ErrorCode EndpointRecv(ZEndpointRecvReq* req);
glcr::ErrorCode ReplyPortSend(ZReplyPortSendReq* req);
glcr::ErrorCode ReplyPortRecv(ZReplyPortRecvReq* req);

View File

@ -1,64 +0,0 @@
#include "syscall/port.h"
#include <glacier/status/error.h>
#include "capability/capability.h"
#include "interrupt/interrupt.h"
#include "scheduler/scheduler.h"
z_err_t PortCreate(ZPortCreateReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto port = glcr::MakeRefCounted<Port>();
*req->port_cap = proc.AddNewCapability(port, ZC_WRITE | ZC_READ);
return glcr::OK;
}
z_err_t PortSend(ZPortSendReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto port_cap = proc.GetCapability(req->port_cap);
RET_ERR(ValidateCapability<Port>(port_cap, ZC_WRITE));
auto port = port_cap->obj<Port>();
return port->Write(req->num_bytes, req->data, req->num_caps, req->caps);
}
z_err_t PortRecv(ZPortRecvReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto port_cap = proc.GetCapability(req->port_cap);
RET_ERR(ValidateCapability<Port>(port_cap, ZC_READ));
auto port = port_cap->obj<Port>();
ZMessage message{
.num_bytes = *req->num_bytes,
.data = const_cast<void*>(req->data),
.num_caps = *req->num_caps,
.caps = req->caps,
};
return port->Read(req->num_bytes, req->data, req->num_caps, req->caps);
}
z_err_t PortPoll(ZPortPollReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto port_cap = proc.GetCapability(req->port_cap);
RET_ERR(ValidateCapability<Port>(port_cap, ZC_READ));
auto port = port_cap->obj<Port>();
// FIXME: Race condition here where this call could block if the last message
// is removed between this check and the port read.
if (!port->HasMessages()) {
return glcr::EMPTY;
}
return port->Read(req->num_bytes, req->data, req->num_caps, req->caps);
}
z_err_t IrqRegister(ZIrqRegisterReq* req) {
auto& proc = gScheduler->CurrentProcess();
if (req->irq_num != Z_IRQ_PCI_BASE) {
// FIXME: Don't hardcode this nonsense.
return glcr::UNIMPLEMENTED;
}
glcr::RefPtr<Port> port = glcr::MakeRefCounted<Port>();
*req->port_cap = proc.AddNewCapability(port, ZC_READ | ZC_WRITE);
RegisterPciPort(port);
return glcr::OK;
}

View File

@ -1,9 +0,0 @@
#pragma once
#include "include/zcall.h"
z_err_t PortCreate(ZPortCreateReq* req);
z_err_t PortSend(ZPortSendReq* req);
z_err_t PortRecv(ZPortRecvReq* req);
z_err_t PortPoll(ZPortPollReq* req);
z_err_t IrqRegister(ZIrqRegisterReq* req);

View File

@ -1,22 +0,0 @@
#include "syscall/reply_port.h"
#include "object/reply_port.h"
#include "scheduler/scheduler.h"
glcr::ErrorCode ReplyPortSend(ZReplyPortSendReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto reply_port_cap = proc.GetCapability(req->reply_port_cap);
ValidateCapability<ReplyPort>(reply_port_cap, ZC_WRITE);
auto reply_port = reply_port_cap->obj<ReplyPort>();
return reply_port->Write(req->num_bytes, req->data, req->num_caps, req->caps);
}
glcr::ErrorCode ReplyPortRecv(ZReplyPortRecvReq* req) {
auto& proc = gScheduler->CurrentProcess();
auto reply_port_cap = proc.GetCapability(req->reply_port_cap);
ValidateCapability<ReplyPort>(reply_port_cap, ZC_READ);
auto reply_port = reply_port_cap->obj<ReplyPort>();
return reply_port->Read(req->num_bytes, req->data, req->num_caps, req->caps);
}

View File

@ -1,9 +0,0 @@
#pragma once
#include <glacier/status/error.h>
#include "include/zcall.h"
glcr::ErrorCode ReplyPortSend(ZReplyPortSendReq* req);
glcr::ErrorCode ReplyPortRecv(ZReplyPortRecvReq* req);

View File

@ -6,13 +6,10 @@
#include "scheduler/scheduler.h"
#include "syscall/address_space.h"
#include "syscall/capability.h"
#include "syscall/channel.h"
#include "syscall/debug.h"
#include "syscall/endpoint.h"
#include "syscall/ipc.h"
#include "syscall/memory_object.h"
#include "syscall/port.h"
#include "syscall/process.h"
#include "syscall/reply_port.h"
#include "syscall/thread.h"
#define EFER 0xC0000080
@ -65,21 +62,18 @@ extern "C" z_err_t SyscallHandler(uint64_t call_id, void* req) {
CASE(MemoryObjectCreatePhysical);
CASE(MemoryObjectCreateContiguous);
CASE(TempPcieConfigObjectCreate);
// syscall/channel.h
// syscall/ipc.h
CASE(ChannelCreate);
CASE(ChannelSend);
CASE(ChannelRecv);
// syscall/port.h
CASE(PortCreate);
CASE(PortSend);
CASE(PortRecv);
CASE(PortPoll);
CASE(IrqRegister);
// syscall/endpoint.h
CASE(EndpointCreate);
CASE(EndpointSend);
CASE(EndpointRecv);
// syscall/reply_port.h
CASE(ReplyPortSend);
CASE(ReplyPortRecv);
// syscall/capability.h