Skip to content

Commit

Permalink
Merge branch 'RPCSX:master' into devel
Browse files Browse the repository at this point in the history
  • Loading branch information
qurious-pixel authored Nov 11, 2023
2 parents 0e219a6 + 37295c1 commit 4721911
Show file tree
Hide file tree
Showing 30 changed files with 654 additions and 585 deletions.
2 changes: 1 addition & 1 deletion 3rdparty/crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.20)
project(libcrypto)
set(PROJECT_PATH crypto)

Expand Down
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ add_subdirectory(rpcsx-os)
add_subdirectory(rpcsx-gpu)
add_subdirectory(hw/amdgpu)
add_subdirectory(rx)

target_compile_definitions(rx PRIVATE
RX_TAG=0
RX_TAG_VERSION=0
)
6 changes: 6 additions & 0 deletions orbis-kernel/include/orbis/KernelAllocator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ void *kalloc(std::size_t size, std::size_t align);
void kfree(void *ptr, std::size_t size);
template <typename T> struct kallocator {
using value_type = T;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using propagate_on_container_move_assignment = std::true_type;

constexpr kallocator() = default;
template <typename U> constexpr kallocator(const kallocator<U> &) noexcept {}

template <typename U> struct rebind {
using other = kallocator<U>;
Expand Down
3 changes: 2 additions & 1 deletion orbis-kernel/include/orbis/KernelContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final {
std::lock_guard lock(m_sem_mtx);
auto [it, inserted] = mIpmiServers.try_emplace(std::move(name), nullptr);
if (inserted) {
it->second = knew<IpmiServer>(name);
it->second = knew<IpmiServer>(it->first);
}

return {it->second.get(), inserted};
Expand Down Expand Up @@ -159,6 +159,7 @@ class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final {
Ref<RcBase> dmemDevice;
Ref<RcBase> blockpoolDevice;
AudioOut *audioOut = nullptr;
uint sdkVersion{};

private:
mutable pthread_mutex_t m_heap_mtx;
Expand Down
7 changes: 7 additions & 0 deletions orbis-kernel/include/orbis/error/ErrorCode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,10 @@ enum class ErrorCode : int {
CAPMODE = 94, // Not permitted in capability mode
};
} // namespace orbis

#define ORBIS_RET_ON_ERROR(...) \
do { \
if (auto errc___ = (__VA_ARGS__); errc___ != ::orbis::ErrorCode{}) { \
return errc___; \
} \
} while (false)
4 changes: 2 additions & 2 deletions orbis-kernel/src/KernelContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ KernelContext::KernelContext() {
pthread_mutex_init(&m_heap_mtx, &mtx_attr);
pthread_mutexattr_destroy(&mtx_attr);

std::printf("orbis::KernelContext initialized, addr=%p\n", this);
std::printf("TSC frequency: %lu\n", getTscFreq());
// std::printf("orbis::KernelContext initialized, addr=%p\n", this);
// std::printf("TSC frequency: %lu\n", getTscFreq());
}
KernelContext::~KernelContext() {}

Expand Down
224 changes: 193 additions & 31 deletions orbis-kernel/src/sys/sys_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ 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;
} // namespace orbis

orbis::SysResult orbis::sys_kqueue(Thread *thread) {
Expand All @@ -81,7 +95,8 @@ orbis::SysResult orbis::sys_kqueue(Thread *thread) {
return {};
}

orbis::SysResult orbis::sys_kqueueex(Thread *thread, ptr<char> name, sint flags) {
orbis::SysResult orbis::sys_kqueueex(Thread *thread, ptr<char> name,
sint flags) {
auto queue = knew<KQueue>();
if (queue == nullptr) {
return ErrorCode::NOMEM;
Expand All @@ -93,6 +108,95 @@ orbis::SysResult orbis::sys_kqueueex(Thread *thread, ptr<char> name, sint flags)
return {};
}

namespace orbis {
static SysResult keventChange(KQueue *kq, KEvent &change) {
auto nodeIt = kq->notes.end();
for (auto it = kq->notes.begin(); it != kq->notes.end(); ++it) {
if (it->event.ident == change.ident && it->event.filter == change.filter) {
nodeIt = it;
break;
}
}

if (change.flags & kEvDelete) {
if (nodeIt == kq->notes.end()) {
return orbis::ErrorCode::NOENT;
}

kq->notes.erase(nodeIt);
nodeIt = kq->notes.end();
}

if (change.flags & kEvAdd) {
if (nodeIt == kq->notes.end()) {
KNote note{
.event = change,
.enabled = true,
};

note.event.flags &= ~(kEvAdd | kEvDelete | kEvDisable | kEvEnable);
kq->notes.push_front(note);
nodeIt = kq->notes.begin();
}
}

if (nodeIt == kq->notes.end()) {
if (change.flags & kEvDelete) {
return {};
}

return orbis::ErrorCode::NOENT;
}

if (change.flags & kEvDisable) {
nodeIt->enabled = false;
}
if (change.flags & kEvEnable) {
nodeIt->enabled = true;
}

if (change.filter == kEvFiltUser) {
auto fflags = 0;
switch (change.fflags & kNoteFFCtrlMask) {
case kNoteFFAnd:
fflags = nodeIt->event.fflags & change.fflags;
break;
case kNoteFFOr:
fflags = nodeIt->event.fflags | change.fflags;
break;
case kNoteFFCopy:
fflags = change.fflags;
break;
}

nodeIt->event.fflags =
(nodeIt->event.fflags & ~kNoteFFlagsMask) | (fflags & kNoteFFlagsMask);

if (change.fflags & kNoteTrigger) {
nodeIt->event.fflags |= kNoteTrigger;
}

if (change.flags & kEvClear) {
nodeIt->event.fflags &= ~kNoteTrigger;
}
}

return {};
}

static orbis::ErrorCode ureadTimespec(orbis::timespec &ts,
orbis::ptr<const orbis::timespec> addr) {
orbis::ErrorCode error = uread(ts, addr);
if (error != orbis::ErrorCode{})
return error;
if (ts.sec < 0 || ts.nsec < 0 || ts.nsec > 1000000000) {
return orbis::ErrorCode::INVAL;
}

return {};
}
} // namespace orbis

orbis::SysResult orbis::sys_kevent(Thread *thread, sint fd,
ptr<KEvent> changelist, sint nchanges,
ptr<KEvent> eventlist, sint nevents,
Expand All @@ -104,57 +208,115 @@ orbis::SysResult orbis::sys_kevent(Thread *thread, sint fd,
return orbis::ErrorCode::BADF;
}

std::lock_guard lock(kqf->mtx);

auto kq = dynamic_cast<KQueue *>(kqf.get());

if (kq == nullptr) {
return orbis::ErrorCode::BADF;
}

if (nchanges != 0) {
for (auto change : std::span(changelist, nchanges)) {
ORBIS_LOG_TODO(__FUNCTION__, change.ident, change.filter, change.flags,
change.fflags, change.data, change.udata);

if (change.flags & kEvAdd) {
// if (change.filter != kEvFiltDisplay && change.filter != kEvFiltGraphicsCore) {
// std::abort();
// }
{
std::lock_guard lock(kqf->mtx);

kq->notes.push_back({
.event = change,
.enabled = (change.flags & kEvDisable) == 0
});
if (nchanges != 0) {
for (auto change : std::span(changelist, nchanges)) {
ORBIS_LOG_TODO(__FUNCTION__, change.ident, change.filter, change.flags,
change.fflags, change.data, change.udata);

kq->notes.back().event.flags &= ~(kEvAdd | kEvClear | kEvDelete | kEvDisable);
if (auto result = keventChange(kq, change); result.value() != 0) {
return result;
}
}
}
}

if (nevents == 0) {
return {};
}

// TODO
using clock = std::chrono::high_resolution_clock;
clock::time_point timeoutPoint = clock::time_point::max();
if (timeout != nullptr) {
timespec _timeout;
auto result = ureadTimespec(_timeout, timeout);
if (result != ErrorCode{}) {
return result;
}

__uint128_t nsec = _timeout.sec;
nsec *= 1000'000'000;
nsec += _timeout.nsec;

if (nsec < INT64_MAX) {
auto now = clock::now();
auto nowValue = now.time_since_epoch().count();

if (nowValue < nowValue + nsec) {
timeoutPoint = now + std::chrono::nanoseconds(nsec);
}
}
}

std::vector<KEvent> result;
result.reserve(nevents);

for (auto &note : kq->notes) {
if (result.size() >= nevents) {
break;
}
while (result.empty()) {
{
std::lock_guard lock(kqf->mtx);
for (auto it = kq->notes.begin(); it != kq->notes.end();) {
if (result.size() >= nevents) {
break;
}

auto &note = *it;

if (!note.enabled) {
continue;
if (!note.enabled) {
++it;
continue;
}

if (note.event.filter == kEvFiltUser) {
if ((note.event.fflags & kNoteTrigger) == 0) {
++it;
continue;
}

auto event = note.event;
event.fflags &= kNoteFFlagsMask;
result.push_back(event);
} else if (note.event.filter == kEvFiltDisplay ||
note.event.filter == kEvFiltGraphicsCore) {
result.push_back(note.event);
} else if (note.event.filter == kEvFiltProc) {
// TODO
if (note.event.fflags & kNoteExec) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
note.event.data = 0;
result.push_back(note.event);
}
} else {
++it;
continue;
}

if (note.event.flags & kEvOneshot) {
it = kq->notes.erase(it);
} else {
++it;
}
}
}

if (note.event.filter == kEvFiltDisplay || note.event.filter == kEvFiltGraphicsCore) {
result.push_back(note.event);
if (!result.empty()) {
break;
}
if (note.event.filter == kEvFiltProc) {
// TODO
std::this_thread::sleep_for(std::chrono::milliseconds(500));
note.event.data = 0;
result.push_back(note.event);

if (timeoutPoint != clock::time_point::max()) {
if (clock::now() >= timeoutPoint) {
break;
}
}

std::this_thread::sleep_for(std::chrono::milliseconds(100));
}

std::memcpy(eventlist, result.data(), result.size() * sizeof(KEvent));
Expand Down
Loading

0 comments on commit 4721911

Please sign in to comment.