From 35f24e7c774dfbd175918b02f4c303e389908245 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Fri, 16 Jun 2023 23:15:28 -0700 Subject: [PATCH] Add a Port poll operation --- zion/include/zcall.h | 5 +++++ zion/include/zerrors.h | 1 + zion/object/port.cpp | 5 +++++ zion/object/port.h | 2 ++ zion/syscall/syscall.cpp | 15 +++++++++++++++ zion/usr/zcall.cpp | 21 +++++++++++++++++++++ 6 files changed, 49 insertions(+) diff --git a/zion/include/zcall.h b/zion/include/zcall.h index a690a24..a9b4f9c 100644 --- a/zion/include/zcall.h +++ b/zion/include/zcall.h @@ -46,6 +46,7 @@ #define Z_PORT_CREATE 0x50 #define Z_PORT_SEND 0x51 #define Z_PORT_RECV 0x52 +#define Z_PORT_POLL 0x53 #define Z_IRQ_REGISTER 0x58 @@ -99,6 +100,10 @@ void ZThreadExit(); uint8_t* bytes, uint64_t num_caps, uint64_t* caps, uint64_t* type, uint64_t* actual_bytes, uint64_t* actual_caps); +[[nodiscard]] z_err_t ZPortPoll(uint64_t port_cap, uint64_t num_bytes, + uint8_t* bytes, uint64_t num_caps, + uint64_t* caps, uint64_t* type, + uint64_t* actual_bytes, uint64_t* actual_caps); [[nodiscard]] z_err_t ZIrqRegister(uint64_t irq_num, uint64_t* port_cap); [[nodiscard]] z_err_t ZDebug(const char* message); diff --git a/zion/include/zerrors.h b/zion/include/zerrors.h index 63815d3..5ce35df 100644 --- a/zion/include/zerrors.h +++ b/zion/include/zerrors.h @@ -10,6 +10,7 @@ #define Z_ERR_BUFF_SIZE 005 #define Z_ERR_NULL 0x6 #define Z_ERR_EXISTS 0x7 +#define Z_ERR_EMPTY 0x8 #define Z_ERR_CAP_NOT_FOUND 0x100 #define Z_ERR_CAP_TYPE 0x101 diff --git a/zion/object/port.cpp b/zion/object/port.cpp index 3e3391c..25d53fd 100644 --- a/zion/object/port.cpp +++ b/zion/object/port.cpp @@ -73,3 +73,8 @@ z_err_t Port::Read(ZMessage& msg) { return Z_OK; } + +bool Port::HasMessages() { + MutexHolder h(mutex_); + return pending_messages_.size() != 0; +} diff --git a/zion/object/port.h b/zion/object/port.h index 3440d04..78fc3e7 100644 --- a/zion/object/port.h +++ b/zion/object/port.h @@ -24,6 +24,8 @@ class Port : public KernelObject { z_err_t Write(const ZMessage& msg); z_err_t Read(ZMessage& msg); + bool HasMessages(); + private: struct Message { uint64_t type; diff --git a/zion/syscall/syscall.cpp b/zion/syscall/syscall.cpp index 0d2c468..e76a7c1 100644 --- a/zion/syscall/syscall.cpp +++ b/zion/syscall/syscall.cpp @@ -208,6 +208,19 @@ z_err_t PortRecv(ZPortRecvReq* req) { 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) { @@ -264,6 +277,8 @@ extern "C" z_err_t SyscallHandler(uint64_t call_id, void* req, void* resp) { return ChannelRecv(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)); diff --git a/zion/usr/zcall.cpp b/zion/usr/zcall.cpp index 7ee1c5e..27999b1 100644 --- a/zion/usr/zcall.cpp +++ b/zion/usr/zcall.cpp @@ -184,6 +184,27 @@ z_err_t ZPortRecv(uint64_t port_cap, uint64_t num_bytes, uint8_t* bytes, return ret; } +z_err_t ZPortPoll(uint64_t port_cap, uint64_t num_bytes, uint8_t* bytes, + uint64_t num_caps, uint64_t* caps, uint64_t* type, + uint64_t* actual_bytes, uint64_t* actual_caps) { + ZPortRecvReq req{ + .port_cap = port_cap, + .message = + { + .type = 0, + .num_bytes = num_bytes, + .bytes = bytes, + .num_caps = num_caps, + .caps = caps, + }, + }; + z_err_t ret = SysCall1(Z_PORT_POLL, &req); + *type = req.message.type; + *actual_bytes = req.message.num_bytes; + *actual_caps = req.message.num_caps; + return ret; +} + z_err_t ZIrqRegister(uint64_t irq_num, uint64_t* port_cap) { ZIrqRegisterReq req{ .irq_num = irq_num,