core/libraries: HLE fiber reimplementation (#1836)

This commit is contained in:
Daniel R. 2024-12-24 13:33:00 +01:00 committed by GitHub
parent 0a4453b912
commit 2c0f986c52
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 564 additions and 193 deletions

View file

@ -6,73 +6,113 @@
#include "common/assert.h"
#include "common/types.h"
#include <atomic>
namespace Core::Loader {
class SymbolsResolver;
}
namespace Libraries::Fiber {
#define ORBIS_FIBER_MAX_NAME_LENGTH (31)
#define ORBIS_FIBER_CONTEXT_MINIMUM_SIZE (512)
typedef void PS4_SYSV_ABI (*SceFiberEntry)(u64 argOnInitialize, u64 argOnRun);
typedef void PS4_SYSV_ABI (*OrbisFiberEntry)(u64 arg_on_initialize, u64 arg_on_run);
enum FiberState : u32 {
None = 0u,
Init = 1u,
Run = 2u,
Suspend = 3u,
Run = 1u,
Idle = 2u,
Terminated = 3u,
};
struct SceFiber {
u64 signature;
FiberState state;
SceFiberEntry entry;
u64 argOnInitialize;
u64 argRun;
u64* pArgRun;
u64 argReturn;
u64* pArgReturn;
u64 sizeContext;
char name[ORBIS_FIBER_MAX_NAME_LENGTH];
void* handle;
enum FiberFlags : u32 {
None = 0x0,
NoUlobjmgr = 0x1,
ContextSizeCheck = 0x10,
SetFpuRegs = 0x100,
};
static_assert(sizeof(SceFiber) <= 256);
struct SceFiberInfo {
u64 size;
SceFiberEntry entry;
u64 argOnInitialize;
void* addrContext;
u64 sizeContext;
struct OrbisFiber;
struct OrbisFiberContext {
struct {
u64 rax, rcx, rdx, rbx, rsp, rbp, r8, r9, r10, r11, r12, r13, r14, r15;
u16 fpucw;
u32 mxcsr;
};
OrbisFiber* current_fiber;
OrbisFiber* prev_fiber;
u64 arg_on_run_to;
u64 arg_on_return;
u64 return_val;
};
struct OrbisFiberData {
OrbisFiberEntry entry;
u64 arg_on_initialize;
u64 arg_on_run_to;
void* stack_addr;
u32* state;
u16 fpucw;
s8 pad[2];
u32 mxcsr;
};
struct OrbisFiber {
u32 magic_start;
std::atomic<FiberState> state;
OrbisFiberEntry entry;
u64 arg_on_initialize;
void* addr_context;
u64 size_context;
char name[ORBIS_FIBER_MAX_NAME_LENGTH + 1];
u64 sizeContextMargin;
OrbisFiberContext* context;
u32 flags;
void* context_start;
void* context_end;
u32 magic_end;
};
static_assert(sizeof(SceFiberInfo) <= 128);
static_assert(sizeof(OrbisFiber) <= 256);
using SceFiberOptParam = void*;
struct OrbisFiberInfo {
u64 size;
OrbisFiberEntry entry;
u64 arg_on_initialize;
void* addr_context;
u64 size_context;
char name[ORBIS_FIBER_MAX_NAME_LENGTH + 1];
u64 size_context_margin;
u8 pad[48];
};
static_assert(sizeof(OrbisFiberInfo) == 128);
s32 PS4_SYSV_ABI sceFiberInitialize(SceFiber* fiber, const char* name, SceFiberEntry entry,
u64 argOnInitialize, void* addrContext, u64 sizeContext,
const SceFiberOptParam* optParam);
struct OrbisFiberOptParam {
u32 magic;
};
static_assert(sizeof(OrbisFiberOptParam) <= 128);
s32 PS4_SYSV_ABI sceFiberOptParamInitialize(SceFiberOptParam* optParam);
s32 PS4_SYSV_ABI sceFiberInitialize(OrbisFiber* fiber, const char* name, OrbisFiberEntry entry,
u64 arg_on_initialize, void* addr_context, u64 size_context,
const OrbisFiberOptParam* opt_param, u32 build_version);
s32 PS4_SYSV_ABI sceFiberFinalize(SceFiber* fiber);
s32 PS4_SYSV_ABI sceFiberOptParamInitialize(OrbisFiberOptParam* opt_param);
s32 PS4_SYSV_ABI sceFiberRun(SceFiber* fiber, u64 argOnRunTo, u64* argOnReturn);
s32 PS4_SYSV_ABI sceFiberFinalize(OrbisFiber* fiber);
s32 PS4_SYSV_ABI sceFiberSwitch(SceFiber* fiber, u64 argOnRunTo, u64* argOnRun);
s32 PS4_SYSV_ABI sceFiberRun(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_on_return);
s32 PS4_SYSV_ABI sceFiberGetSelf(SceFiber** fiber);
s32 PS4_SYSV_ABI sceFiberSwitch(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_on_run);
s32 PS4_SYSV_ABI sceFiberReturnToThread(u64 argOnReturn, u64* argOnRun);
s32 PS4_SYSV_ABI sceFiberGetSelf(OrbisFiber** fiber);
s32 PS4_SYSV_ABI sceFiberGetInfo(SceFiber* fiber, SceFiberInfo* fiberInfo);
s32 PS4_SYSV_ABI sceFiberReturnToThread(u64 arg_on_return, u64* arg_on_run);
s32 PS4_SYSV_ABI sceFiberGetInfo(OrbisFiber* fiber, OrbisFiberInfo* fiber_info);
s32 PS4_SYSV_ABI sceFiberStartContextSizeCheck(u32 flags);
s32 PS4_SYSV_ABI sceFiberStopContextSizeCheck(void);
s32 PS4_SYSV_ABI sceFiberRename(SceFiber* fiber, const char* name);
s32 PS4_SYSV_ABI sceFiberRename(OrbisFiber* fiber, const char* name);
void RegisterlibSceFiber(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Fiber