core: Reorganize

This commit is contained in:
GPUCode
2023-11-06 01:11:54 +02:00
parent 89cf4dbfcb
commit 369d92fa56
73 changed files with 724 additions and 572 deletions

View File

@@ -0,0 +1,89 @@
#include "common/debug.h"
#include "core/hle/kernel/objects/event_queue.h"
#include "Lib/Timer.h"
namespace Core::Kernel {
EqueueInternal::~EqueueInternal() = default;
int EqueueInternal::addEvent(const EqueueEvent& event) {
std::scoped_lock lock{m_mutex};
if (m_events.size() > 0) {
BREAKPOINT();
}
// TODO check if event is already exists and return it. Currently we just add in m_events array
m_events.push_back(event);
if (event.isTriggered) {
BREAKPOINT(); // we don't support that either yet
}
return 0;
}
int EqueueInternal::waitForEvents(SceKernelEvent* ev, int num, u32 micros) {
std::unique_lock lock{m_mutex};
u32 timeElapsed = 0;
Lib::Timer t;
t.Start();
for (;;) {
int ret = getTriggeredEvents(ev, num);
if (ret > 0 || (timeElapsed >= micros && micros != 0)) {
return ret;
}
if (micros == 0) {
m_cond.wait(lock);
} else {
m_cond.wait_for(lock, std::chrono::microseconds(micros - timeElapsed));
}
timeElapsed = static_cast<uint32_t>(t.GetTimeSec() * 1000000.0);
}
return 0;
}
bool EqueueInternal::triggerEvent(u64 ident, s16 filter, void* trigger_data) {
std::scoped_lock lock{m_mutex};
if (m_events.size() > 1) {
BREAKPOINT(); // we currently support one event
}
auto& event = m_events[0];
if (event.filter.trigger_event_func != nullptr) {
event.filter.trigger_event_func(&event, trigger_data);
} else {
event.isTriggered = true;
}
m_cond.notify_one();
return true;
}
int EqueueInternal::getTriggeredEvents(SceKernelEvent* ev, int num) {
int ret = 0;
if (m_events.size() > 1) {
BREAKPOINT(); // we currently support one event
}
auto& event = m_events[0];
if (event.isTriggered) {
ev[ret++] = event.event;
if (event.filter.reset_event_func != nullptr) {
event.filter.reset_event_func(&event);
}
}
return ret;
}
} // namespace Core::Kernel

View File

@@ -0,0 +1,78 @@
#pragma once
#include <mutex>
#include <string>
#include <vector>
#include "common/types.h"
namespace Core::Kernel {
constexpr s16 EVFILT_READ = -1;
constexpr s16 EVFILT_WRITE = -2;
constexpr s16 EVFILT_AIO = -3; // attached to aio requests
constexpr s16 EVFILT_VNODE = -4; // attached to vnodes
constexpr s16 EVFILT_PROC = -5; // attached to struct proc
constexpr s16 EVFILT_SIGNAL = -6; // attached to struct proc
constexpr s16 EVFILT_TIMER = -7; // timers
constexpr s16 EVFILT_FS = -9; // filesystem events
constexpr s16 EVFILT_LIO = -10; // attached to lio requests
constexpr s16 EVFILT_USER = -11; // User events
constexpr s16 EVFILT_POLLING = -12;
constexpr s16 EVFILT_VIDEO_OUT = -13;
constexpr s16 EVFILT_GRAPHICS_CORE = -14;
constexpr s16 EVFILT_HRTIMER = -15;
constexpr s16 EVFILT_UVD_TRAP = -16;
constexpr s16 EVFILT_VCE_TRAP = -17;
constexpr s16 EVFILT_SDMA_TRAP = -18;
constexpr s16 EVFILT_REG_EV = -19;
constexpr s16 EVFILT_GPU_EXCEPTION = -20;
constexpr s16 EVFILT_GPU_SYSTEM_EXCEPTION = -21;
constexpr s16 EVFILT_GPU_DBGGC_EV = -22;
constexpr s16 EVFILT_SYSCOUNT = 22;
class EqueueInternal;
struct EqueueEvent;
using TriggerFunc = void (*)(EqueueEvent* event, void* trigger_data);
using ResetFunc = void (*)(EqueueEvent* event);
using DeleteFunc = void (*)(EqueueInternal* eq, EqueueEvent* event);
struct SceKernelEvent {
u64 ident = 0; /* identifier for this event */
s16 filter = 0; /* filter for event */
u16 flags = 0;
u32 fflags = 0;
s64 data = 0;
void* udata = nullptr; /* opaque user data identifier */
};
struct Filter {
void* data = nullptr;
TriggerFunc trigger_event_func = nullptr;
ResetFunc reset_event_func = nullptr;
DeleteFunc delete_event_func = nullptr;
};
struct EqueueEvent {
bool isTriggered = false;
SceKernelEvent event;
Filter filter;
};
class EqueueInternal {
public:
EqueueInternal() = default;
virtual ~EqueueInternal();
void setName(const std::string& m_name) { this->m_name = m_name; }
int addEvent(const EqueueEvent& event);
int waitForEvents(SceKernelEvent* ev, int num, u32 micros);
bool triggerEvent(u64 ident, s16 filter, void* trigger_data);
int getTriggeredEvents(SceKernelEvent* ev, int num);
private:
std::string m_name;
std::mutex m_mutex;
std::vector<EqueueEvent> m_events;
std::condition_variable m_cond;
};
} // namespace Core::Kernel

View File

@@ -0,0 +1,68 @@
#include "core/hle/kernel/objects/physical_memory.h"
namespace Core::Kernel {
static u64 AlignUp(u64 pos, u64 align) {
return (align != 0 ? (pos + (align - 1)) & ~(align - 1) : pos);
}
bool PhysicalMemory::Alloc(u64 searchStart, u64 searchEnd, u64 len, u64 alignment,
u64* physAddrOut, int memoryType) {
std::scoped_lock lock{m_mutex};
u64 find_free_pos = 0;
// iterate through allocated blocked and find the next free position
for (const auto& block : m_allocatedBlocks) {
u64 n = block.start_addr + block.size;
if (n > find_free_pos) {
find_free_pos = n;
}
}
// align free position
find_free_pos = AlignUp(find_free_pos, alignment);
// if the new position is between searchStart - searchEnd , allocate a new block
if (find_free_pos >= searchStart && find_free_pos + len <= searchEnd) {
AllocatedBlock block{};
block.size = len;
block.start_addr = find_free_pos;
block.memoryType = memoryType;
block.gpu_mode = GPU::MemoryMode::NoAccess;
block.map_size = 0;
block.map_virtual_addr = 0;
block.prot = 0;
block.cpu_mode = VirtualMemory::MemoryMode::NoAccess;
m_allocatedBlocks.push_back(block);
*physAddrOut = find_free_pos;
return true;
}
return false;
}
bool PhysicalMemory::Map(u64 virtual_addr, u64 phys_addr, u64 len, int prot,
VirtualMemory::MemoryMode cpu_mode, GPU::MemoryMode gpu_mode) {
std::scoped_lock lock{m_mutex};
for (auto& b : m_allocatedBlocks) {
if (phys_addr >= b.start_addr && phys_addr < b.start_addr + b.size) {
if (b.map_virtual_addr != 0 || b.map_size != 0) {
return false;
}
b.map_virtual_addr = virtual_addr;
b.map_size = len;
b.prot = prot;
b.cpu_mode = cpu_mode;
b.gpu_mode = gpu_mode;
return true;
}
}
return false;
}
} // namespace Core::Kernel

View File

@@ -0,0 +1,36 @@
#pragma once
#include <mutex>
#include <vector>
#include "common/types.h"
#include "core/virtual_memory.h"
#include "core/PS4/GPU/gpu_memory.h"
namespace Core::Kernel {
class PhysicalMemory {
public:
struct AllocatedBlock {
u64 start_addr;
u64 size;
int memoryType;
u64 map_virtual_addr;
u64 map_size;
int prot;
VirtualMemory::MemoryMode cpu_mode;
GPU::MemoryMode gpu_mode;
};
PhysicalMemory() {}
virtual ~PhysicalMemory() {}
public:
bool Alloc(u64 searchStart, u64 searchEnd, u64 len, u64 alignment, u64* physAddrOut, int memoryType);
bool Map(u64 virtual_addr, u64 phys_addr, u64 len, int prot, VirtualMemory::MemoryMode cpu_mode, GPU::MemoryMode gpu_mode);
private:
std::vector<AllocatedBlock> m_allocatedBlocks;
std::mutex m_mutex;
};
} // namespace Core::Kernel