mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-06 15:05:59 +00:00
merge rpcsx-gpu and rpcsx-os
initial watchdog implementation implement gpu -> os events implement main gfx queue
This commit is contained in:
parent
8e9711e0f6
commit
0c16e294d4
236 changed files with 4649 additions and 4669 deletions
|
|
@ -9,6 +9,8 @@
|
|||
#include <unistd.h>
|
||||
|
||||
static const std::uint64_t g_allocProtWord = 0xDEADBEAFBADCAFE1;
|
||||
static constexpr auto kHeapBaseAddress = 0x600'0000'0000;
|
||||
static constexpr auto kHeapSize = 0x2'0000'0000;
|
||||
|
||||
namespace orbis {
|
||||
thread_local Thread *g_currentThread;
|
||||
|
|
@ -16,7 +18,7 @@ thread_local Thread *g_currentThread;
|
|||
KernelContext &g_context = *[]() -> KernelContext * {
|
||||
// Allocate global shared kernel memory
|
||||
// TODO: randomize for hardening and reduce size
|
||||
auto ptr = mmap(reinterpret_cast<void *>(0x200'0000'0000), 0x2'0000'0000,
|
||||
auto ptr = mmap(reinterpret_cast<void *>(kHeapBaseAddress), kHeapSize,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
|
||||
if (ptr == MAP_FAILED)
|
||||
|
|
@ -166,15 +168,32 @@ void *KernelContext::kalloc(std::size_t size, std::size_t align) {
|
|||
align = std::max<std::size_t>(align, __STDCPP_DEFAULT_NEW_ALIGNMENT__);
|
||||
auto heap = reinterpret_cast<std::uintptr_t>(m_heap_next);
|
||||
heap = (heap + (align - 1)) & ~(align - 1);
|
||||
|
||||
if (heap + size > kHeapBaseAddress + kHeapSize) {
|
||||
std::fprintf(stderr, "out of kernel memory");
|
||||
std::abort();
|
||||
}
|
||||
// Check overflow
|
||||
if (heap + size < heap) {
|
||||
std::fprintf(stderr, "too big allocation");
|
||||
std::abort();
|
||||
}
|
||||
|
||||
auto result = reinterpret_cast<void *>(heap);
|
||||
std::memcpy(std::bit_cast<std::byte *>(result) + size, &g_allocProtWord,
|
||||
sizeof(g_allocProtWord));
|
||||
m_heap_next = reinterpret_cast<void *>(heap + size + sizeof(g_allocProtWord));
|
||||
// Check overflow
|
||||
if (heap + size < heap)
|
||||
std::abort();
|
||||
if (heap + size > (uintptr_t)&g_context + 0x1'0000'0000)
|
||||
std::abort();
|
||||
|
||||
if (true) {
|
||||
heap = reinterpret_cast<std::uintptr_t>(m_heap_next);
|
||||
align = std::min<std::size_t>(align, 4096);
|
||||
heap = (heap + (align - 1)) & ~(align - 1);
|
||||
size = 4096;
|
||||
::mmap(reinterpret_cast<void *>(heap), size, PROT_NONE, MAP_FIXED, -1, 0);
|
||||
|
||||
m_heap_next = reinterpret_cast<void *>(heap + size);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
#include "event.hpp"
|
||||
|
||||
#include "thread/Process.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
orbis::KNote::~KNote() {
|
||||
while (!emitters.empty()) {
|
||||
emitters.back()->unsubscribe(this);
|
||||
}
|
||||
|
||||
if (linked == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -14,7 +20,7 @@ orbis::KNote::~KNote() {
|
|||
}
|
||||
}
|
||||
|
||||
void orbis::EventEmitter::emit(uint filter, uint fflags, intptr_t data) {
|
||||
void orbis::EventEmitter::emit(sshort filter, uint fflags, intptr_t data) {
|
||||
std::lock_guard lock(mutex);
|
||||
|
||||
for (auto note : notes) {
|
||||
|
|
@ -40,3 +46,28 @@ void orbis::EventEmitter::emit(uint filter, uint fflags, intptr_t data) {
|
|||
note->queue->cv.notify_all(note->queue->mtx);
|
||||
}
|
||||
}
|
||||
|
||||
void orbis::EventEmitter::subscribe(KNote *note) {
|
||||
std::lock_guard lock(mutex);
|
||||
notes.insert(note);
|
||||
note->emitters.emplace_back(this);
|
||||
}
|
||||
|
||||
void orbis::EventEmitter::unsubscribe(KNote *note) {
|
||||
std::lock_guard lock(mutex);
|
||||
notes.erase(note);
|
||||
|
||||
auto it = std::ranges::find(note->emitters, this);
|
||||
if (it == note->emitters.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::size_t index = it - note->emitters.begin();
|
||||
auto lastEmitter = note->emitters.size() - 1;
|
||||
|
||||
if (index != lastEmitter) {
|
||||
std::swap(note->emitters[index], note->emitters[lastEmitter]);
|
||||
}
|
||||
|
||||
note->emitters.pop_back();
|
||||
}
|
||||
|
|
@ -223,6 +223,10 @@ orbis::SysResult orbis::sysIpmiServerReceivePacket(Thread *thread,
|
|||
ptr<uint> unk;
|
||||
};
|
||||
|
||||
if (paramsSz != sizeof(IpmiServerReceivePacketParams)) {
|
||||
return orbis::ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
IpmiServerReceivePacketParams _params;
|
||||
|
||||
ORBIS_RET_ON_ERROR(
|
||||
|
|
@ -265,9 +269,6 @@ orbis::SysResult orbis::sysIpmiServerReceivePacket(Thread *thread,
|
|||
auto asyncMessage = (IpmiAsyncMessageHeader *)_packet.message.data();
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, server->name, asyncMessage->methodId,
|
||||
asyncMessage->numInData, asyncMessage->pid);
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, server->name,
|
||||
*(std::uint64_t *)(*(long *)server->eventHandler + 0x18));
|
||||
}
|
||||
|
||||
if (_params.bufferSize < _packet.message.size()) {
|
||||
|
|
@ -380,11 +381,13 @@ orbis::SysResult orbis::sysIpmiSessionRespondSync(Thread *thread,
|
|||
clientTid = session->server->tidToClientTid.at(thread->tid);
|
||||
}
|
||||
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, session->client->name, _params.errorCode);
|
||||
|
||||
if (_params.errorCode != 0) {
|
||||
ORBIS_LOG_ERROR(__FUNCTION__, session->client->name, _params.errorCode);
|
||||
thread->where();
|
||||
|
||||
// HACK: completely broken audio audio support should not be visible
|
||||
// HACK: completely broken audio support should not be visible
|
||||
if (session->client->name == "SceSysAudioSystemIpc" &&
|
||||
_params.errorCode == -1) {
|
||||
_params.errorCode = 0;
|
||||
|
|
@ -1268,6 +1271,10 @@ orbis::SysResult orbis::sysIpmiClientWaitEventFlag(Thread *thread,
|
|||
|
||||
static_assert(sizeof(IpmiWaitEventFlagParam) == 0x28);
|
||||
|
||||
if (paramsSz != sizeof(IpmiWaitEventFlagParam)) {
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
|
||||
IpmiWaitEventFlagParam _params;
|
||||
ORBIS_RET_ON_ERROR(uread(_params, ptr<IpmiWaitEventFlagParam>(params)));
|
||||
|
||||
|
|
|
|||
|
|
@ -113,17 +113,15 @@ static SysResult keventChange(KQueue *kq, KEvent &change, Thread *thread) {
|
|||
nodeIt->file = fd;
|
||||
|
||||
if (auto eventEmitter = fd->event) {
|
||||
std::unique_lock lock(eventEmitter->mutex);
|
||||
// if (change.filter == kEvFiltWrite) {
|
||||
// nodeIt->triggered = true;
|
||||
// kq->cv.notify_all(kq->mtx);
|
||||
// }
|
||||
eventEmitter->subscribe(&*nodeIt);
|
||||
nodeIt->triggered = true;
|
||||
eventEmitter->notes.insert(&*nodeIt);
|
||||
kq->cv.notify_all(kq->mtx);
|
||||
} else if (note.file->hostFd < 0) {
|
||||
ORBIS_LOG_ERROR("Unimplemented event emitter", change.ident);
|
||||
}
|
||||
} else if (change.filter == kEvFiltGraphicsCore ||
|
||||
change.filter == kEvFiltDisplay) {
|
||||
g_context.deviceEventEmitter->subscribe(&*nodeIt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -172,19 +170,14 @@ static SysResult keventChange(KQueue *kq, KEvent &change, Thread *thread) {
|
|||
nodeIt->triggered = true;
|
||||
kq->cv.notify_all(kq->mtx);
|
||||
}
|
||||
} else if (change.filter == kEvFiltGraphicsCore) {
|
||||
} else if (change.filter == kEvFiltDisplay && change.ident >> 48 == 0x6301) {
|
||||
nodeIt->triggered = true;
|
||||
|
||||
if (change.ident == 0x84) {
|
||||
// clock change event
|
||||
nodeIt->event.data |= 1000ull << 16; // clock
|
||||
}
|
||||
kq->cv.notify_all(kq->mtx);
|
||||
} else if (change.filter == kEvFiltDisplay) {
|
||||
if (change.ident != 0x51000100000000 && change.ident != 0x63010100000000) {
|
||||
nodeIt->triggered = true;
|
||||
kq->cv.notify_all(kq->mtx);
|
||||
}
|
||||
} else if (change.filter == kEvFiltGraphicsCore && change.ident == 0x84) {
|
||||
nodeIt->triggered = true;
|
||||
nodeIt->event.data |= 1000ull << 16; // clock
|
||||
|
||||
kq->cv.notify_all(kq->mtx);
|
||||
}
|
||||
|
||||
return {};
|
||||
|
|
|
|||
|
|
@ -307,8 +307,8 @@ SysResult kern_sysctl(Thread *thread, ptr<sint> name, uint namelen,
|
|||
case sysctl_ctl::unspec: {
|
||||
switch (name[1]) {
|
||||
case 3: {
|
||||
std::fprintf(stderr, " unspec - get name of '%s'\n",
|
||||
std::string((char *)new_, newlen).c_str());
|
||||
// std::fprintf(stderr, " unspec - get name of '%s'\n",
|
||||
// std::string((char *)new_, newlen).c_str());
|
||||
auto searchName = std::string_view((char *)new_, newlen);
|
||||
auto *dest = (std::uint32_t *)old;
|
||||
std::uint32_t count = 0;
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ orbis::ErrorCode orbis::umtx_cv_wait(Thread *thread, ptr<ucond> cv,
|
|||
ORBIS_LOG_FATAL("umtx_cv_wait: UNKNOWN wflags", wflags);
|
||||
return ErrorCode::INVAL;
|
||||
}
|
||||
if ((wflags & kCvWaitClockId) != 0 && ut + 1) {
|
||||
if ((wflags & kCvWaitClockId) != 0 && ut + 1 && cv->clockid != 0) {
|
||||
ORBIS_LOG_WARNING("umtx_cv_wait: CLOCK_ID", wflags, cv->clockid);
|
||||
// std::abort();
|
||||
return ErrorCode::NOSYS;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue