[zion] Move port calls to new syscall process.

This commit is contained in:
Drew Galbraith 2023-06-20 14:55:54 -07:00
parent 77bb3acfb4
commit bd431b94ce
11 changed files with 118 additions and 175 deletions

View File

@ -18,6 +18,5 @@ class Port {
template <typename T>
z_err_t Port::WriteMessage(const T& obj, uint64_t cap) {
return ZPortSend(port_cap_, sizeof(obj),
reinterpret_cast<const uint8_t*>(&obj), 1, &cap);
return ZPortSend(port_cap_, sizeof(obj), &obj, 1, &cap);
}

View File

@ -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<uint8_t *>(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<uint8_t *>(msg), &caps,
cap));
if (bytes != sizeof(uint64_t)) {
return Z_ERR_INVALID;

View File

@ -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))) {

View File

@ -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

View File

@ -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);

View File

@ -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

81
zion/syscall/port.cpp Normal file
View File

@ -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<Port>();
*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<Port>();
RET_IF_NULL(port);
ZMessage message{
.num_bytes = req->num_bytes,
.data = const_cast<void*>(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<Port>();
RET_IF_NULL(port);
ZMessage message{
.num_bytes = *req->num_bytes,
.data = const_cast<void*>(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<Port>();
RET_IF_NULL(port);
if (!port->HasMessages()) {
return Z_ERR_EMPTY;
}
ZMessage message{
.num_bytes = *req->num_bytes,
.data = const_cast<void*>(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> port = MakeRefCounted<Port>();
*req->port_cap = proc.AddNewCapability(port, ZC_READ | ZC_WRITE);
RegisterPciPort(port);
return Z_OK;
}

9
zion/syscall/port.h Normal file
View File

@ -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);

View File

@ -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<Capability>& cap, uint64_t permissions) {
return Z_OK;
}
z_err_t PortCreate(ZPortCreateResp* resp) {
auto& proc = gScheduler->CurrentProcess();
auto port = MakeRefCounted<Port>();
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<Port>();
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<Port>();
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<Port>();
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> port = MakeRefCounted<Port>();
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<ZPortCreateResp*>(resp));
case Z_PORT_SEND:
return PortSend(reinterpret_cast<ZPortSendReq*>(req));
case Z_PORT_RECV:
return PortRecv(reinterpret_cast<ZPortRecvReq*>(req));
case Z_PORT_POLL:
return PortPoll(reinterpret_cast<ZPortRecvReq*>(req));
case Z_IRQ_REGISTER:
return IrqRegister(reinterpret_cast<ZIrqRegisterReq*>(req),
reinterpret_cast<ZIrqRegisterResp*>(resp));
// syscall/port.h
CASE(PortCreate);
CASE(PortSend);
CASE(PortRecv);
CASE(PortPoll);
CASE(IrqRegister);
case Z_CAP_DUPLICATE:
return CapDuplicate(reinterpret_cast<ZCapDuplicateReq*>(req),
reinterpret_cast<ZCapDuplicateResp*>(resp));

View File

@ -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<void*>(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,

View File

@ -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;
};