Skip to content

Commit

Permalink
[orbis-kernel] implement pipe kevents
Browse files Browse the repository at this point in the history
  • Loading branch information
DHrpcs3 committed Nov 13, 2023
1 parent 0f86008 commit 0a957b8
Show file tree
Hide file tree
Showing 12 changed files with 262 additions and 122 deletions.
107 changes: 1 addition & 106 deletions orbis-kernel/include/orbis/event.hpp
Original file line number Diff line number Diff line change
@@ -1,117 +1,12 @@
#pragma once

#include "file.hpp"
#include "orbis-config.hpp"
#include "note.hpp"
#include "utils/SharedCV.hpp"
#include "utils/SharedMutex.hpp"
#include <list>
#include <mutex>
#include <set>

namespace orbis {
static constexpr auto kEvFiltRead = -1;
static constexpr auto kEvFiltWrite = -2;
static constexpr auto kEvFiltAio = -3;
static constexpr auto kEvFiltVnode = -4;
static constexpr auto kEvFiltProc = -5;
static constexpr auto kEvFiltSignal = -6;
static constexpr auto kEvFiltTimer = -7;
static constexpr auto kEvFiltFs = -9;
static constexpr auto kEvFiltLio = -10;
static constexpr auto kEvFiltUser = -11;
static constexpr auto kEvFiltPolling = -12;
static constexpr auto kEvFiltDisplay = -13;
static constexpr auto kEvFiltGraphicsCore = -14;
static constexpr auto kEvFiltHrTimer = -15;
static constexpr auto kEvFiltUvdTrap = -16;
static constexpr auto kEvFiltVceTrap = -17;
static constexpr auto kEvFiltSdmaTrap = -18;
static constexpr auto kEvFiltRegEv = -19;
static constexpr auto kEvFiltGpuException = -20;
static constexpr auto kEvFiltGpuSystemException = -21;
static constexpr auto kEvFiltGpuDbgGcEv = -22;
static constexpr auto kEvFiltSysCount = 22;

// actions
static constexpr auto kEvAdd = 0x0001;
static constexpr auto kEvDelete = 0x0002;
static constexpr auto kEvEnable = 0x0004;
static constexpr auto kEvDisable = 0x0008;

// flags
static constexpr auto kEvOneshot = 0x0010;
static constexpr auto kEvClear = 0x0020;
static constexpr auto kEvReceipt = 0x0040;
static constexpr auto kEvDispatch = 0x0080;
static constexpr auto kEvSysFlags = 0xf000;
static constexpr auto kEvFlag1 = 0x2000;

static constexpr auto kEvEof = 0x8000;
static constexpr auto kEvError = 0x4000;

// kEvFiltUser
static constexpr auto kNoteFFNop = 0x00000000;
static constexpr auto kNoteFFAnd = 0x40000000;
static constexpr auto kNoteFFOr = 0x80000000;
static constexpr auto kNoteFFCopy = 0xc0000000;
static constexpr auto kNoteFFCtrlMask = 0xc0000000;
static constexpr auto kNoteFFlagsMask = 0x00ffffff;
static constexpr auto kNoteTrigger = 0x01000000;

// kEvFiltProc
static constexpr auto kNoteExit = 0x80000000;
static constexpr auto kNoteFork = 0x40000000;
static constexpr auto kNoteExec = 0x20000000;

struct KEvent {
uintptr_t ident;
sshort filter;
ushort flags;
uint fflags;
intptr_t data;
ptr<void> udata;
};

struct KQueue;

struct KNote {
shared_mutex mutex;
Ref<KQueue> queue;
KEvent event{};
bool enabled = true;
bool triggered = false;
void *linked = nullptr; // TODO: use Ref<>

~KNote();
};

struct KQueue : orbis::File {
shared_cv cv;
std::list<KNote, kallocator<KNote>> notes;
};

struct EventEmitter {
shared_mutex mutex;
std::set<KNote *, std::less<>, kallocator<KNote *>> notes;

void emit(uint noteId, intptr_t data = 0) {
std::lock_guard lock(mutex);

for (auto note : notes) {
if ((note->event.fflags & noteId) == 0) {
continue;
}

std::lock_guard lock(note->mutex);

if (note->triggered) {
continue;
}

note->triggered = true;
note->event.data = data;
note->queue->cv.notify_all(note->queue->mtx);
}
}
};
} // namespace orbis
2 changes: 2 additions & 0 deletions orbis-kernel/include/orbis/file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "KernelAllocator.hpp"
#include "error/ErrorCode.hpp"
#include "note.hpp"
#include "stat.hpp"
#include "utils/Rc.hpp"
#include "utils/SharedMutex.hpp"
Expand Down Expand Up @@ -44,6 +45,7 @@ struct FileOps {

struct File : RcBase {
shared_mutex mtx;
EventEmitter event;
const FileOps *ops = nullptr;
Ref<RcBase> device;
std::uint64_t nextOff = 0;
Expand Down
16 changes: 12 additions & 4 deletions orbis-kernel/include/orbis/ipmi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ struct IpmiSession : RcBase {
EventFlag evf{0, 0};
shared_cv connectCv;
bool expectedOutput = false; // TODO: verify
bool connected = false; // TODO: implement more states
bool connected = false; // TODO: implement more states
sint connectionStatus{0};
};

Expand Down Expand Up @@ -121,9 +121,8 @@ SysResult sysIpmiDestroySession(Thread *thread, ptr<uint> result, uint kid,

SysResult sysIpmiServerReceivePacket(Thread *thread, ptr<uint> result, uint kid,
ptr<void> params, uint64_t paramsSz);
SysResult sysIpmiSendConnectResult(Thread *thread, ptr<uint> result,
uint kid, ptr<void> params,
uint64_t paramsSz);
SysResult sysIpmiSendConnectResult(Thread *thread, ptr<uint> result, uint kid,
ptr<void> params, uint64_t paramsSz);
SysResult sysIpmiSessionRespondSync(Thread *thread, ptr<uint> result, uint kid,
ptr<void> params, uint64_t paramsSz);
SysResult sysIpmiSessionGetClientPid(Thread *thread, ptr<uint> result, uint kid,
Expand All @@ -137,4 +136,13 @@ SysResult sysIpmiSessionGetUserData(Thread *thread, ptr<uint> result, uint kid,
ptr<void> params, uint64_t paramsSz);
SysResult sysIpmiServerGetName(Thread *thread, ptr<uint> result, uint kid,
ptr<void> params, uint64_t paramsSz);
SysResult sysIpmiClientPollEventFlag(Thread *thread, ptr<uint> result,
uint kid, ptr<void> params,
uint64_t paramsSz);
SysResult sysIpmiSessionWaitEventFlag(Thread *thread, ptr<uint> result,
uint kid, ptr<void> params,
uint64_t paramsSz);
SysResult sysIpmiSessionSetEventFlag(Thread *thread, ptr<uint> result, uint kid,
ptr<void> params, uint64_t paramsSz);

} // namespace orbis
92 changes: 92 additions & 0 deletions orbis-kernel/include/orbis/note.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#pragma once

#include "KernelAllocator.hpp"
#include "orbis-config.hpp"
#include "utils/SharedMutex.hpp"
#include <mutex>
#include <set>

namespace orbis {

static constexpr auto kEvFiltRead = -1;
static constexpr auto kEvFiltWrite = -2;
static constexpr auto kEvFiltAio = -3;
static constexpr auto kEvFiltVnode = -4;
static constexpr auto kEvFiltProc = -5;
static constexpr auto kEvFiltSignal = -6;
static constexpr auto kEvFiltTimer = -7;
static constexpr auto kEvFiltFs = -9;
static constexpr auto kEvFiltLio = -10;
static constexpr auto kEvFiltUser = -11;
static constexpr auto kEvFiltPolling = -12;
static constexpr auto kEvFiltDisplay = -13;
static constexpr auto kEvFiltGraphicsCore = -14;
static constexpr auto kEvFiltHrTimer = -15;
static constexpr auto kEvFiltUvdTrap = -16;
static constexpr auto kEvFiltVceTrap = -17;
static constexpr auto kEvFiltSdmaTrap = -18;
static constexpr auto kEvFiltRegEv = -19;
static constexpr auto kEvFiltGpuException = -20;
static constexpr auto kEvFiltGpuSystemException = -21;
static constexpr auto kEvFiltGpuDbgGcEv = -22;
static constexpr auto kEvFiltSysCount = 22;

// actions
static constexpr auto kEvAdd = 0x0001;
static constexpr auto kEvDelete = 0x0002;
static constexpr auto kEvEnable = 0x0004;
static constexpr auto kEvDisable = 0x0008;

// flags
static constexpr auto kEvOneshot = 0x0010;
static constexpr auto kEvClear = 0x0020;
static constexpr auto kEvReceipt = 0x0040;
static constexpr auto kEvDispatch = 0x0080;
static constexpr auto kEvSysFlags = 0xf000;
static constexpr auto kEvFlag1 = 0x2000;

static constexpr auto kEvEof = 0x8000;
static constexpr auto kEvError = 0x4000;

// kEvFiltUser
static constexpr auto kNoteFFNop = 0x00000000;
static constexpr auto kNoteFFAnd = 0x40000000;
static constexpr auto kNoteFFOr = 0x80000000;
static constexpr auto kNoteFFCopy = 0xc0000000;
static constexpr auto kNoteFFCtrlMask = 0xc0000000;
static constexpr auto kNoteFFlagsMask = 0x00ffffff;
static constexpr auto kNoteTrigger = 0x01000000;

// kEvFiltProc
static constexpr auto kNoteExit = 0x80000000;
static constexpr auto kNoteFork = 0x40000000;
static constexpr auto kNoteExec = 0x20000000;

struct KEvent {
uintptr_t ident;
sshort filter;
ushort flags;
uint fflags;
intptr_t data;
ptr<void> udata;
};

struct KQueue;
struct KNote {
shared_mutex mutex;
Ref<KQueue> queue;
KEvent event{};
bool enabled = true;
bool triggered = false;
void *linked = nullptr; // TODO: use Ref<>

~KNote();
};

struct EventEmitter {
shared_mutex mutex;
std::set<KNote *, std::less<>, kallocator<KNote *>> notes;

void emit(uint filter, uint fflags = 0, intptr_t data = 0);
};
} // namespace orbis
3 changes: 3 additions & 0 deletions orbis-kernel/include/orbis/pipe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
#include "KernelAllocator.hpp"
#include "file.hpp"
#include "utils/Rc.hpp"
#include "utils/SharedCV.hpp"
#include "utils/SharedMutex.hpp"

namespace orbis {
struct Pipe final : File {
shared_cv cv;
kvector<std::byte> data;
};

Expand Down
23 changes: 23 additions & 0 deletions orbis-kernel/src/event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,26 @@ orbis::KNote::~KNote() {
proc->event.notes.erase(this);
}
}

void orbis::EventEmitter::emit(uint filter, uint fflags, intptr_t data) {
std::lock_guard lock(mutex);

for (auto note : notes) {
if (note->event.filter != filter) {
continue;
}
if (fflags != 0 && ((note->event.fflags & fflags) == 0)) {
continue;
}

std::lock_guard lock(note->mutex);

if (note->triggered) {
continue;
}

note->triggered = true;
note->event.data = data;
note->queue->cv.notify_all(note->queue->mtx);
}
}
70 changes: 70 additions & 0 deletions orbis-kernel/src/ipmi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -704,3 +704,73 @@ orbis::SysResult orbis::sysIpmiServerGetName(Thread *thread, ptr<uint> result,

return uwrite<uint>(result, 0);
}

orbis::SysResult orbis::sysIpmiClientPollEventFlag(Thread *thread,
ptr<uint> result, uint kid,
ptr<void> params,
uint64_t paramsSz) {
struct IpmiPollEventFlagParam {
uint64_t index;
uint64_t patternSet;
uint64_t mode;
ptr<uint64_t> pPatternSet;
};

static_assert(sizeof(IpmiPollEventFlagParam) == 0x20);

if (paramsSz != sizeof(IpmiPollEventFlagParam)) {
return ErrorCode::INVAL;
}

IpmiPollEventFlagParam _params;
ORBIS_RET_ON_ERROR(uread(_params, ptr<IpmiPollEventFlagParam>(params)));

auto client = thread->tproc->ipmiMap.get(kid).cast<IpmiClient>();

if (client == nullptr) {
return ErrorCode::INVAL;
}

ORBIS_LOG_TODO(__FUNCTION__, client->name, _params.index, _params.patternSet, _params.mode, _params.pPatternSet);
ORBIS_RET_ON_ERROR(uwrite(_params.pPatternSet, 0u));
// client->evf.set(_params.a);
return ErrorCode::BUSY;
}

orbis::SysResult orbis::sysIpmiSessionWaitEventFlag(Thread *thread,
ptr<uint> result, uint kid,
ptr<void> params,
uint64_t paramsSz) {
ORBIS_LOG_TODO(__FUNCTION__, paramsSz);
thread->where();
return uwrite<uint>(result, 0);
}

orbis::SysResult orbis::sysIpmiSessionSetEventFlag(Thread *thread,
ptr<uint> result, uint kid,
ptr<void> params,
uint64_t paramsSz) {
struct IpmiSetEventFlagParam {
uint64_t patternSet;
uint64_t index;
};

static_assert(sizeof(IpmiSetEventFlagParam) == 0x10);

if (paramsSz != sizeof(IpmiSetEventFlagParam)) {
return ErrorCode::INVAL;
}

IpmiSetEventFlagParam _params;
ORBIS_RET_ON_ERROR(uread(_params, ptr<IpmiSetEventFlagParam>(params)));

auto session = thread->tproc->ipmiMap.get(kid).cast<IpmiSession>();

if (session == nullptr) {
return ErrorCode::INVAL;
}

ORBIS_LOG_TODO(__FUNCTION__, session->client->name, _params.patternSet, _params.index);
session->evf.set(_params.patternSet);
return uwrite<uint>(result, 0);
}
Loading

0 comments on commit 0a957b8

Please sign in to comment.