diff --git a/lib/mammoth/include/mammoth/port.h b/lib/mammoth/include/mammoth/port.h index 5e174d3..8344a05 100644 --- a/lib/mammoth/include/mammoth/port.h +++ b/lib/mammoth/include/mammoth/port.h @@ -18,6 +18,5 @@ class Port { template z_err_t Port::WriteMessage(const T& obj, uint64_t cap) { - return ZPortSend(port_cap_, sizeof(obj), - reinterpret_cast(&obj), 1, &cap); + return ZPortSend(port_cap_, sizeof(obj), &obj, 1, &cap); } diff --git a/lib/mammoth/src/port.cpp b/lib/mammoth/src/port.cpp index 9942757..131f331 100644 --- a/lib/mammoth/src/port.cpp +++ b/lib/mammoth/src/port.cpp @@ -7,10 +7,10 @@ Port::Port(uint64_t port_cap) : port_cap_(port_cap) {} z_err_t Port::PollForIntCap(uint64_t *msg, uint64_t *cap) { - uint64_t bytes, caps; - RET_ERR(ZPortPoll(port_cap_, sizeof(uint64_t), - reinterpret_cast(msg), /* num_caps= */ 1, cap, - &bytes, &caps)); + uint64_t bytes = sizeof(uint64_t); + uint64_t caps = 1; + RET_ERR(ZPortPoll(port_cap_, &bytes, reinterpret_cast(msg), &caps, + cap)); if (bytes != sizeof(uint64_t)) { return Z_ERR_INVALID; diff --git a/sys/denali/ahci/ahci_driver.cpp b/sys/denali/ahci/ahci_driver.cpp index c7d036e..0337ddb 100644 --- a/sys/denali/ahci/ahci_driver.cpp +++ b/sys/denali/ahci/ahci_driver.cpp @@ -141,7 +141,7 @@ void AhciDriver::InterruptLoop() { dbgln("Starting interrupt loop"); while (true) { uint64_t bytes, caps; - check(ZPortRecv(irq_port_cap_, 0, 0, 0, 0, &bytes, &caps)); + check(ZPortRecv(irq_port_cap_, &bytes, nullptr, &caps, nullptr)); for (uint64_t i = 0; i < 32; i++) { if (devices_[i] != nullptr && devices_[i]->IsInit() && (ahci_hba_->interrupt_status & (1 << i))) { diff --git a/zion/CMakeLists.txt b/zion/CMakeLists.txt index 7bf6eb1..9b959d2 100644 --- a/zion/CMakeLists.txt +++ b/zion/CMakeLists.txt @@ -30,6 +30,7 @@ add_executable(zion syscall/address_space.cpp syscall/channel.cpp syscall/memory_object.cpp + syscall/port.cpp syscall/process.cpp syscall/syscall.cpp syscall/syscall_enter.s diff --git a/zion/include/zcall.h b/zion/include/zcall.h index 352b5cb..d5c07de 100644 --- a/zion/include/zcall.h +++ b/zion/include/zcall.h @@ -113,17 +113,15 @@ SYS5(ChannelSend, z_cap_t, chan_cap, uint64_t, num_bytes, const void*, data, 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, - const void* data, uint64_t num_caps, - z_cap_t* caps); -[[nodiscard]] z_err_t ZPortRecv(z_cap_t port_cap, uint64_t num_bytes, - void* data, uint64_t num_caps, z_cap_t* caps, - uint64_t* actual_bytes, uint64_t* actual_caps); -[[nodiscard]] z_err_t ZPortPoll(z_cap_t port_cap, uint64_t num_bytes, - void* data, uint64_t num_caps, z_cap_t* caps, - uint64_t* actual_bytes, uint64_t* actual_caps); -[[nodiscard]] z_err_t ZIrqRegister(uint64_t irq_num, z_cap_t* port_cap); +SYS1(PortCreate, z_cap_t*, port_cap); +SYS5(PortSend, z_cap_t, port_cap, uint64_t, num_bytes, const void*, data, + uint64_t, num_caps, z_cap_t*, caps); +SYS5(PortRecv, z_cap_t, port_cap, uint64_t*, num_bytes, void*, data, uint64_t*, + num_caps, z_cap_t*, caps); +SYS5(PortPoll, z_cap_t, port_cap, uint64_t*, num_bytes, void*, data, uint64_t*, + num_caps, z_cap_t*, caps); + +SYS2(IrqRegister, uint64_t, irq_num, z_cap_t*, port_cap); [[nodiscard]] z_err_t ZCapDuplicate(z_cap_t cap_in, z_cap_t* cap_out); diff --git a/zion/include/ztypes.h b/zion/include/ztypes.h index 17cd947..3d73768 100644 --- a/zion/include/ztypes.h +++ b/zion/include/ztypes.h @@ -54,12 +54,12 @@ 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 -#define Z_PORT_RECV 0x52 -#define Z_PORT_POLL 0x53 +const uint64_t kZionPortCreate = 0x50; +const uint64_t kZionPortSend = 0x51; +const uint64_t kZionPortRecv = 0x52; +const uint64_t kZionPortPoll = 0x53; -#define Z_IRQ_REGISTER 0x58 +const uint64_t kZionIrqRegister = 0x58; #define Z_IRQ_PCI_BASE 0x30 diff --git a/zion/syscall/port.cpp b/zion/syscall/port.cpp new file mode 100644 index 0000000..6014d07 --- /dev/null +++ b/zion/syscall/port.cpp @@ -0,0 +1,81 @@ +#include "syscall/port.h" + +#include "interrupt/interrupt.h" +#include "scheduler/scheduler.h" +#include "syscall/syscall.h" + +z_err_t PortCreate(ZPortCreateReq* req) { + auto& proc = gScheduler->CurrentProcess(); + auto port = MakeRefCounted(); + *req->port_cap = proc.AddNewCapability(port, ZC_WRITE | ZC_READ); + return Z_OK; +} + +z_err_t PortSend(ZPortSendReq* req) { + auto& proc = gScheduler->CurrentProcess(); + auto port_cap = proc.GetCapability(req->port_cap); + RET_ERR(ValidateCap(port_cap, ZC_WRITE)); + + auto port = port_cap->obj(); + RET_IF_NULL(port); + ZMessage message{ + .num_bytes = req->num_bytes, + .data = const_cast(req->data), + .num_caps = req->num_caps, + .caps = req->caps, + }; + return port->Write(message); +} + +z_err_t PortRecv(ZPortRecvReq* req) { + auto& proc = gScheduler->CurrentProcess(); + auto port_cap = proc.GetCapability(req->port_cap); + RET_ERR(ValidateCap(port_cap, ZC_READ)); + + auto port = port_cap->obj(); + RET_IF_NULL(port); + ZMessage message{ + .num_bytes = *req->num_bytes, + .data = const_cast(req->data), + .num_caps = *req->num_caps, + .caps = req->caps, + }; + RET_ERR(port->Read(message)); + *req->num_bytes = message.num_bytes; + *req->num_caps = message.num_caps; + return Z_OK; +} + +z_err_t PortPoll(ZPortPollReq* req) { + auto& proc = gScheduler->CurrentProcess(); + auto port_cap = proc.GetCapability(req->port_cap); + RET_ERR(ValidateCap(port_cap, ZC_READ)); + + auto port = port_cap->obj(); + RET_IF_NULL(port); + if (!port->HasMessages()) { + return Z_ERR_EMPTY; + } + ZMessage message{ + .num_bytes = *req->num_bytes, + .data = const_cast(req->data), + .num_caps = *req->num_caps, + .caps = req->caps, + }; + RET_ERR(port->Read(message)); + *req->num_bytes = message.num_bytes; + *req->num_caps = message.num_caps; + return Z_OK; +} + +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 Z_ERR_UNIMPLEMENTED; + } + RefPtr port = MakeRefCounted(); + *req->port_cap = proc.AddNewCapability(port, ZC_READ | ZC_WRITE); + RegisterPciPort(port); + return Z_OK; +} diff --git a/zion/syscall/port.h b/zion/syscall/port.h new file mode 100644 index 0000000..221e71e --- /dev/null +++ b/zion/syscall/port.h @@ -0,0 +1,9 @@ +#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/syscall.cpp b/zion/syscall/syscall.cpp index 5059071..b093113 100644 --- a/zion/syscall/syscall.cpp +++ b/zion/syscall/syscall.cpp @@ -15,6 +15,7 @@ #include "syscall/address_space.h" #include "syscall/channel.h" #include "syscall/memory_object.h" +#include "syscall/port.h" #include "syscall/process.h" #include "syscall/thread.h" #include "usr/zcall_internal.h" @@ -62,58 +63,6 @@ z_err_t ValidateCap(const RefPtr& cap, uint64_t permissions) { return Z_OK; } -z_err_t PortCreate(ZPortCreateResp* resp) { - auto& proc = gScheduler->CurrentProcess(); - auto port = MakeRefCounted(); - resp->port_cap = proc.AddNewCapability(port, ZC_WRITE | ZC_READ); - return Z_OK; -} - -z_err_t PortSend(ZPortSendReq* req) { - auto& proc = gScheduler->CurrentProcess(); - auto port_cap = proc.GetCapability(req->port_cap); - RET_ERR(ValidateCap(port_cap, ZC_WRITE)); - - auto port = port_cap->obj(); - RET_IF_NULL(port); - return port->Write(req->message); -} - -z_err_t PortRecv(ZPortRecvReq* req) { - auto& proc = gScheduler->CurrentProcess(); - auto port_cap = proc.GetCapability(req->port_cap); - RET_ERR(ValidateCap(port_cap, ZC_READ)); - - auto port = port_cap->obj(); - RET_IF_NULL(port); - return port->Read(req->message); -} - -z_err_t PortPoll(ZPortRecvReq* req) { - auto& proc = gScheduler->CurrentProcess(); - auto port_cap = proc.GetCapability(req->port_cap); - RET_ERR(ValidateCap(port_cap, ZC_READ)); - - auto port = port_cap->obj(); - RET_IF_NULL(port); - if (!port->HasMessages()) { - return Z_ERR_EMPTY; - } - return port->Read(req->message); -} - -z_err_t IrqRegister(ZIrqRegisterReq* req, ZIrqRegisterResp* resp) { - auto& proc = gScheduler->CurrentProcess(); - if (req->irq_num != Z_IRQ_PCI_BASE) { - // FIXME: Don't hardcode this nonsense. - return Z_ERR_UNIMPLEMENTED; - } - RefPtr port = MakeRefCounted(); - resp->port_cap = proc.AddNewCapability(port, ZC_READ | ZC_WRITE); - RegisterPciPort(port); - return Z_OK; -} - z_err_t CapDuplicate(ZCapDuplicateReq* req, ZCapDuplicateResp* resp) { auto& proc = gScheduler->CurrentProcess(); auto cap = proc.GetCapability(req->cap); @@ -149,17 +98,12 @@ extern "C" z_err_t SyscallHandler(uint64_t call_id, void* req, void* resp) { CASE(ChannelCreate); CASE(ChannelSend); CASE(ChannelRecv); - case Z_PORT_CREATE: - return PortCreate(reinterpret_cast(resp)); - case Z_PORT_SEND: - return PortSend(reinterpret_cast(req)); - case Z_PORT_RECV: - return PortRecv(reinterpret_cast(req)); - case Z_PORT_POLL: - return PortPoll(reinterpret_cast(req)); - case Z_IRQ_REGISTER: - return IrqRegister(reinterpret_cast(req), - reinterpret_cast(resp)); + // syscall/port.h + CASE(PortCreate); + CASE(PortSend); + CASE(PortRecv); + CASE(PortPoll); + CASE(IrqRegister); case Z_CAP_DUPLICATE: return CapDuplicate(reinterpret_cast(req), reinterpret_cast(resp)); diff --git a/zion/usr/zcall.cpp b/zion/usr/zcall.cpp index 9af2c85..f754da1 100644 --- a/zion/usr/zcall.cpp +++ b/zion/usr/zcall.cpp @@ -19,73 +19,6 @@ z_err_t SysCall1(uint64_t number, const void* first) { return SysCall2(number, first, 0); } -z_err_t ZPortCreate(z_cap_t* port_cap) { - ZPortCreateResp resp; - z_err_t ret = SysCall2(Z_PORT_CREATE, 0, &resp); - *port_cap = resp.port_cap; - return ret; -} - -z_err_t ZPortSend(z_cap_t port_cap, uint64_t num_bytes, const void* data, - uint64_t num_caps, z_cap_t* caps) { - ZPortSendReq req{.port_cap = port_cap, - .message = { - .num_bytes = num_bytes, - .data = const_cast(data), - .num_caps = num_caps, - .caps = caps, - }}; - return SysCall1(Z_PORT_SEND, &req); -} - -z_err_t ZPortRecv(z_cap_t port_cap, uint64_t num_bytes, void* data, - uint64_t num_caps, z_cap_t* caps, uint64_t* actual_bytes, - uint64_t* actual_caps) { - ZPortRecvReq req{ - .port_cap = port_cap, - .message = - { - .num_bytes = num_bytes, - .data = data, - .num_caps = num_caps, - .caps = caps, - }, - }; - z_err_t ret = SysCall1(Z_PORT_RECV, &req); - *actual_bytes = req.message.num_bytes; - *actual_caps = req.message.num_caps; - return ret; -} - -z_err_t ZPortPoll(z_cap_t port_cap, uint64_t num_bytes, void* data, - uint64_t num_caps, z_cap_t* caps, uint64_t* actual_bytes, - uint64_t* actual_caps) { - ZPortRecvReq req{ - .port_cap = port_cap, - .message = - { - .num_bytes = num_bytes, - .data = data, - .num_caps = num_caps, - .caps = caps, - }, - }; - z_err_t ret = SysCall1(Z_PORT_POLL, &req); - *actual_bytes = req.message.num_bytes; - *actual_caps = req.message.num_caps; - return ret; -} - -z_err_t ZIrqRegister(uint64_t irq_num, z_cap_t* port_cap) { - ZIrqRegisterReq req{ - .irq_num = irq_num, - }; - ZIrqRegisterResp resp; - z_err_t ret = SysCall2(Z_IRQ_REGISTER, &req, &resp); - *port_cap = resp.port_cap; - return ret; -} - z_err_t ZCapDuplicate(z_cap_t cap_in, z_cap_t* cap_out) { ZCapDuplicateReq req{ .cap = cap_in, diff --git a/zion/usr/zcall_internal.h b/zion/usr/zcall_internal.h index bed791c..9f5c122 100644 --- a/zion/usr/zcall_internal.h +++ b/zion/usr/zcall_internal.h @@ -12,28 +12,6 @@ struct ZMessage { z_cap_t* caps; }; -struct ZPortCreateResp { - z_cap_t port_cap; -}; - -struct ZPortSendReq { - z_cap_t port_cap; - ZMessage message; -}; - -struct ZPortRecvReq { - z_cap_t port_cap; - ZMessage message; -}; - -struct ZIrqRegisterReq { - uint64_t irq_num; -}; - -struct ZIrqRegisterResp { - z_cap_t port_cap; -}; - struct ZCapDuplicateReq { z_cap_t cap; };