Add a Port poll operation
This commit is contained in:
parent
21b73b5b92
commit
35f24e7c77
|
@ -46,6 +46,7 @@
|
||||||
#define Z_PORT_CREATE 0x50
|
#define Z_PORT_CREATE 0x50
|
||||||
#define Z_PORT_SEND 0x51
|
#define Z_PORT_SEND 0x51
|
||||||
#define Z_PORT_RECV 0x52
|
#define Z_PORT_RECV 0x52
|
||||||
|
#define Z_PORT_POLL 0x53
|
||||||
|
|
||||||
#define Z_IRQ_REGISTER 0x58
|
#define Z_IRQ_REGISTER 0x58
|
||||||
|
|
||||||
|
@ -99,6 +100,10 @@ void ZThreadExit();
|
||||||
uint8_t* bytes, uint64_t num_caps,
|
uint8_t* bytes, uint64_t num_caps,
|
||||||
uint64_t* caps, uint64_t* type,
|
uint64_t* caps, uint64_t* type,
|
||||||
uint64_t* actual_bytes, uint64_t* actual_caps);
|
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 ZIrqRegister(uint64_t irq_num, uint64_t* port_cap);
|
||||||
|
|
||||||
[[nodiscard]] z_err_t ZDebug(const char* message);
|
[[nodiscard]] z_err_t ZDebug(const char* message);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#define Z_ERR_BUFF_SIZE 005
|
#define Z_ERR_BUFF_SIZE 005
|
||||||
#define Z_ERR_NULL 0x6
|
#define Z_ERR_NULL 0x6
|
||||||
#define Z_ERR_EXISTS 0x7
|
#define Z_ERR_EXISTS 0x7
|
||||||
|
#define Z_ERR_EMPTY 0x8
|
||||||
|
|
||||||
#define Z_ERR_CAP_NOT_FOUND 0x100
|
#define Z_ERR_CAP_NOT_FOUND 0x100
|
||||||
#define Z_ERR_CAP_TYPE 0x101
|
#define Z_ERR_CAP_TYPE 0x101
|
||||||
|
|
|
@ -73,3 +73,8 @@ z_err_t Port::Read(ZMessage& msg) {
|
||||||
|
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Port::HasMessages() {
|
||||||
|
MutexHolder h(mutex_);
|
||||||
|
return pending_messages_.size() != 0;
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ class Port : public KernelObject {
|
||||||
z_err_t Write(const ZMessage& msg);
|
z_err_t Write(const ZMessage& msg);
|
||||||
z_err_t Read(ZMessage& msg);
|
z_err_t Read(ZMessage& msg);
|
||||||
|
|
||||||
|
bool HasMessages();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Message {
|
struct Message {
|
||||||
uint64_t type;
|
uint64_t type;
|
||||||
|
|
|
@ -208,6 +208,19 @@ z_err_t PortRecv(ZPortRecvReq* req) {
|
||||||
return port->Read(req->message);
|
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) {
|
z_err_t IrqRegister(ZIrqRegisterReq* req, ZIrqRegisterResp* resp) {
|
||||||
auto& proc = gScheduler->CurrentProcess();
|
auto& proc = gScheduler->CurrentProcess();
|
||||||
if (req->irq_num != Z_IRQ_PCI_BASE) {
|
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<ZChannelRecvReq*>(req));
|
return ChannelRecv(reinterpret_cast<ZChannelRecvReq*>(req));
|
||||||
case Z_PORT_RECV:
|
case Z_PORT_RECV:
|
||||||
return PortRecv(reinterpret_cast<ZPortRecvReq*>(req));
|
return PortRecv(reinterpret_cast<ZPortRecvReq*>(req));
|
||||||
|
case Z_PORT_POLL:
|
||||||
|
return PortPoll(reinterpret_cast<ZPortRecvReq*>(req));
|
||||||
case Z_IRQ_REGISTER:
|
case Z_IRQ_REGISTER:
|
||||||
return IrqRegister(reinterpret_cast<ZIrqRegisterReq*>(req),
|
return IrqRegister(reinterpret_cast<ZIrqRegisterReq*>(req),
|
||||||
reinterpret_cast<ZIrqRegisterResp*>(resp));
|
reinterpret_cast<ZIrqRegisterResp*>(resp));
|
||||||
|
|
|
@ -184,6 +184,27 @@ z_err_t ZPortRecv(uint64_t port_cap, uint64_t num_bytes, uint8_t* bytes,
|
||||||
return ret;
|
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) {
|
z_err_t ZIrqRegister(uint64_t irq_num, uint64_t* port_cap) {
|
||||||
ZIrqRegisterReq req{
|
ZIrqRegisterReq req{
|
||||||
.irq_num = irq_num,
|
.irq_num = irq_num,
|
||||||
|
|
Loading…
Reference in New Issue