diff --git a/zion/CMakeLists.txt b/zion/CMakeLists.txt index df45647..4057051 100644 --- a/zion/CMakeLists.txt +++ b/zion/CMakeLists.txt @@ -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 diff --git a/zion/syscall/channel.cpp b/zion/syscall/channel.cpp deleted file mode 100644 index 975d74b..0000000 --- a/zion/syscall/channel.cpp +++ /dev/null @@ -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(chan_cap, ZC_WRITE)); - - auto chan = chan_cap->obj(); - 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(chan_cap, ZC_READ)); - - auto chan = chan_cap->obj(); - return chan->Read(req->num_bytes, req->data, req->num_caps, req->caps); -} diff --git a/zion/syscall/channel.h b/zion/syscall/channel.h deleted file mode 100644 index 36feb24..0000000 --- a/zion/syscall/channel.h +++ /dev/null @@ -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); diff --git a/zion/syscall/endpoint.cpp b/zion/syscall/endpoint.cpp deleted file mode 100644 index 088d7ee..0000000 --- a/zion/syscall/endpoint.cpp +++ /dev/null @@ -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_cap, ZC_WRITE); - auto endpoint = endpoint_cap->obj(); - - 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_cap, ZC_READ); - auto endpoint = endpoint_cap->obj(); - - return endpoint->Read(req->num_bytes, req->data, req->reply_port_cap); -} diff --git a/zion/syscall/endpoint.h b/zion/syscall/endpoint.h deleted file mode 100644 index 64594ac..0000000 --- a/zion/syscall/endpoint.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -#include "include/zcall.h" - -glcr::ErrorCode EndpointCreate(ZEndpointCreateReq* req); - -glcr::ErrorCode EndpointSend(ZEndpointSendReq* req); - -glcr::ErrorCode EndpointRecv(ZEndpointRecvReq* req); diff --git a/zion/syscall/ipc.cpp b/zion/syscall/ipc.cpp new file mode 100644 index 0000000..a29c9ce --- /dev/null +++ b/zion/syscall/ipc.cpp @@ -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(chan_cap, ZC_WRITE)); + + auto chan = chan_cap->obj(); + 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(chan_cap, ZC_READ)); + + auto chan = chan_cap->obj(); + 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(); + *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_cap, ZC_WRITE)); + + auto port = port_cap->obj(); + 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_cap, ZC_READ)); + + auto port = port_cap->obj(); + ZMessage message{ + .num_bytes = *req->num_bytes, + .data = const_cast(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_cap, ZC_READ)); + + auto port = port_cap->obj(); + // 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 = glcr::MakeRefCounted(); + *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_cap, ZC_WRITE); + auto endpoint = endpoint_cap->obj(); + + 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_cap, ZC_READ); + auto endpoint = endpoint_cap->obj(); + + 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(reply_port_cap, ZC_WRITE); + auto reply_port = reply_port_cap->obj(); + + 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(reply_port_cap, ZC_READ); + auto reply_port = reply_port_cap->obj(); + + return reply_port->Read(req->num_bytes, req->data, req->num_caps, req->caps); +} diff --git a/zion/syscall/ipc.h b/zion/syscall/ipc.h new file mode 100644 index 0000000..4a3ae97 --- /dev/null +++ b/zion/syscall/ipc.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +#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); diff --git a/zion/syscall/port.cpp b/zion/syscall/port.cpp deleted file mode 100644 index 17624c7..0000000 --- a/zion/syscall/port.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "syscall/port.h" - -#include - -#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(); - *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_cap, ZC_WRITE)); - - auto port = port_cap->obj(); - 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_cap, ZC_READ)); - - auto port = port_cap->obj(); - ZMessage message{ - .num_bytes = *req->num_bytes, - .data = const_cast(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_cap, ZC_READ)); - - auto port = port_cap->obj(); - // 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 = glcr::MakeRefCounted(); - *req->port_cap = proc.AddNewCapability(port, ZC_READ | ZC_WRITE); - RegisterPciPort(port); - return glcr::OK; -} diff --git a/zion/syscall/port.h b/zion/syscall/port.h deleted file mode 100644 index 221e71e..0000000 --- a/zion/syscall/port.h +++ /dev/null @@ -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); diff --git a/zion/syscall/reply_port.cpp b/zion/syscall/reply_port.cpp deleted file mode 100644 index 32f2da4..0000000 --- a/zion/syscall/reply_port.cpp +++ /dev/null @@ -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(reply_port_cap, ZC_WRITE); - auto reply_port = reply_port_cap->obj(); - - 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(reply_port_cap, ZC_READ); - auto reply_port = reply_port_cap->obj(); - - return reply_port->Read(req->num_bytes, req->data, req->num_caps, req->caps); -} diff --git a/zion/syscall/reply_port.h b/zion/syscall/reply_port.h deleted file mode 100644 index 4b4d34f..0000000 --- a/zion/syscall/reply_port.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include - -#include "include/zcall.h" - -glcr::ErrorCode ReplyPortSend(ZReplyPortSendReq* req); - -glcr::ErrorCode ReplyPortRecv(ZReplyPortRecvReq* req); diff --git a/zion/syscall/syscall.cpp b/zion/syscall/syscall.cpp index 11efd24..99eaae3 100644 --- a/zion/syscall/syscall.cpp +++ b/zion/syscall/syscall.cpp @@ -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