commit
1474e9d87d
|
@ -31,6 +31,7 @@ bld/
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
[Ll]og/
|
[Ll]og/
|
||||||
[Ll]ogs/
|
[Ll]ogs/
|
||||||
|
[Bb]uild/
|
||||||
|
|
||||||
# Visual Studio 2015/2017 cache/options directory
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
.vs/
|
.vs/
|
||||||
|
|
|
@ -22,3 +22,7 @@
|
||||||
path = third-party/zydis
|
path = third-party/zydis
|
||||||
url = https://github.com/zyantific/zydis.git
|
url = https://github.com/zyantific/zydis.git
|
||||||
shallow = true
|
shallow = true
|
||||||
|
[submodule "third-party/winpthread"]
|
||||||
|
path = third-party/winpthread
|
||||||
|
url = https://github.com/shadps4/winpthread.git
|
||||||
|
branch = main
|
||||||
|
|
|
@ -15,8 +15,8 @@ include_directories(third-party/sdl/)
|
||||||
include_directories(third-party/fmt/include)
|
include_directories(third-party/fmt/include)
|
||||||
include_directories(third-party/magic_enum/include)
|
include_directories(third-party/magic_enum/include)
|
||||||
include_directories(third-party/zydis/include/Zydis)
|
include_directories(third-party/zydis/include/Zydis)
|
||||||
|
include_directories(third-party/winpthread/include)
|
||||||
add_subdirectory("third-party")
|
add_subdirectory("third-party")
|
||||||
|
|
||||||
#=================== EXAMPLE ===================
|
#=================== EXAMPLE ===================
|
||||||
|
|
||||||
add_executable(shadps4
|
add_executable(shadps4
|
||||||
|
@ -34,13 +34,15 @@ add_executable(shadps4
|
||||||
src/Core/Memory.h
|
src/Core/Memory.h
|
||||||
src/Core/PS4/Linker.cpp
|
src/Core/PS4/Linker.cpp
|
||||||
src/Core/PS4/Linker.h
|
src/Core/PS4/Linker.h
|
||||||
"src/Util/Singleton.h" "src/Util/Disassembler.cpp" "src/Util/Disassembler.h" "src/Util/StringUtil.h" "src/Core/PS4/Util/aerolib.h" "src/Core/PS4/Loader/SymbolsResolver.h" "src/Core/PS4/Loader/SymbolsResolver.cpp" "src/Core/PS4/HLE/Libs.cpp" "src/Core/PS4/HLE/Libs.h" "src/Core/PS4/HLE/LibC.cpp" "src/Core/PS4/HLE/LibC.h" "src/Lib/Timer.cpp" "src/Lib/Timer.h" "src/Core/PS4/HLE/LibKernel.cpp" "src/Core/PS4/HLE/LibKernel.h" "src/Core/PS4/HLE/LibSceVideoOut.cpp" "src/Core/PS4/HLE/LibSceVideoOut.h" "src/Core/PS4/HLE/LibSceGnmDriver.cpp" "src/Core/PS4/HLE/LibSceGnmDriver.h")
|
"src/Util/Singleton.h" "src/Util/Disassembler.cpp" "src/Util/Disassembler.h" "src/Util/StringUtil.h" "src/Core/PS4/Util/aerolib.h" "src/Core/PS4/Loader/SymbolsResolver.h" "src/Core/PS4/Loader/SymbolsResolver.cpp" "src/Core/PS4/HLE/Libs.cpp" "src/Core/PS4/HLE/Libs.h" "src/Core/PS4/HLE/LibC.cpp" "src/Core/PS4/HLE/LibC.h" "src/Lib/Timer.cpp" "src/Lib/Timer.h" "src/Core/PS4/HLE/LibKernel.cpp" "src/Core/PS4/HLE/LibKernel.h" "src/Core/PS4/HLE/LibSceVideoOut.cpp" "src/Core/PS4/HLE/LibSceVideoOut.h" "src/Core/PS4/HLE/LibSceGnmDriver.cpp" "src/Core/PS4/HLE/LibSceGnmDriver.h" "src/Core/PS4/HLE/Kernel/ThreadManagement.cpp" "src/Core/PS4/HLE/Kernel/ThreadManagement.h" "src/Core/PS4/HLE/ErrorCodes.h")
|
||||||
|
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
|
|
||||||
target_link_libraries(shadps4 PUBLIC fmt spdlog IMGUI SDL3-shared ${OPENGL_LIBRARY})
|
target_link_libraries(shadps4 PUBLIC fmt spdlog IMGUI SDL3-shared ${OPENGL_LIBRARY})
|
||||||
|
|
||||||
add_custom_command(TARGET shadps4 POST_BUILD
|
add_custom_command(TARGET shadps4 POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
$<TARGET_FILE:SDL3-shared>
|
$<TARGET_FILE:SDL3-shared>
|
||||||
$<TARGET_FILE_DIR:shadps4>)
|
$<TARGET_FILE_DIR:shadps4>)
|
||||||
|
add_custom_command(TARGET shadps4 POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
|
"${PROJECT_SOURCE_DIR}/third-party/winpthread/bin/libwinpthread-1.dll" $<TARGET_FILE_DIR:shadps4>)
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
constexpr int SCE_OK = 0;
|
||||||
|
|
||||||
|
constexpr int SCE_KERNEL_ERROR_ENOMEM = 0x8002000c;//Insufficient memory
|
||||||
|
constexpr int SCE_KERNEL_ERROR_EINVAL = 0x80020016;//null or invalid states
|
|
@ -0,0 +1,131 @@
|
||||||
|
#include "ThreadManagement.h"
|
||||||
|
#include "../ErrorCodes.h"
|
||||||
|
|
||||||
|
namespace HLE::Libs::LibKernel::ThreadManagement
|
||||||
|
{
|
||||||
|
|
||||||
|
thread_local PthreadInternal* g_pthread_self = nullptr;
|
||||||
|
PThreadCxt* g_pthread_cxt = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
void Pthread_Init_Self_MainThread() {
|
||||||
|
g_pthread_self = new PthreadInternal{};
|
||||||
|
scePthreadAttrInit(&g_pthread_self->attr);
|
||||||
|
g_pthread_self->pth = pthread_self();
|
||||||
|
g_pthread_self->name = "Main_Thread";
|
||||||
|
}
|
||||||
|
|
||||||
|
int scePthreadAttrInit(ScePthreadAttr* attr) {
|
||||||
|
|
||||||
|
*attr = new PthreadAttrInternal{};
|
||||||
|
|
||||||
|
int result = pthread_attr_init(&(*attr)->pth_attr);
|
||||||
|
|
||||||
|
(*attr)->affinity = 0x7f;
|
||||||
|
(*attr)->guard_size = 0x1000;
|
||||||
|
|
||||||
|
SceKernelSchedParam param{};
|
||||||
|
param.sched_priority = 700;
|
||||||
|
|
||||||
|
result = (result == 0 ? scePthreadAttrSetinheritsched(attr, 4) : result);
|
||||||
|
result = (result == 0 ? scePthreadAttrSetschedparam(attr, ¶m) : result);
|
||||||
|
result = (result == 0 ? scePthreadAttrSetschedpolicy(attr, SCHED_OTHER) : result);
|
||||||
|
result = (result == 0 ? scePthreadAttrSetdetachstate(attr, PTHREAD_CREATE_JOINABLE) : result);
|
||||||
|
|
||||||
|
switch (result) {
|
||||||
|
case 0: return SCE_OK;
|
||||||
|
case ENOMEM: return SCE_KERNEL_ERROR_ENOMEM;
|
||||||
|
default: return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int scePthreadAttrSetdetachstate(ScePthreadAttr* attr, int detachstate) {
|
||||||
|
|
||||||
|
if (attr == nullptr || *attr == nullptr) {
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pstate = PTHREAD_CREATE_JOINABLE;
|
||||||
|
switch (detachstate) {
|
||||||
|
case 0: pstate = PTHREAD_CREATE_JOINABLE; break;
|
||||||
|
case 1: pstate = PTHREAD_CREATE_DETACHED; break;
|
||||||
|
default:
|
||||||
|
__debugbreak(); //unknown state
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = pthread_attr_setdetachstate(&(*attr)->pth_attr, pstate);
|
||||||
|
|
||||||
|
(*attr)->detached = (pstate == PTHREAD_CREATE_DETACHED);
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
return SCE_OK;
|
||||||
|
}
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scePthreadAttrSetinheritsched(ScePthreadAttr* attr, int inheritSched) {
|
||||||
|
|
||||||
|
if (attr == nullptr || *attr == nullptr) {
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pinherit_sched = PTHREAD_INHERIT_SCHED;
|
||||||
|
switch (inheritSched) {
|
||||||
|
case 0: pinherit_sched = PTHREAD_EXPLICIT_SCHED; break;
|
||||||
|
case 4: pinherit_sched = PTHREAD_INHERIT_SCHED; break;
|
||||||
|
default: __debugbreak(); // unknown inheritSched
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = pthread_attr_setinheritsched(&(*attr)->pth_attr, pinherit_sched);
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
return SCE_OK;
|
||||||
|
}
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scePthreadAttrSetschedparam(ScePthreadAttr* attr, const SceKernelSchedParam* param) {
|
||||||
|
|
||||||
|
if (param == nullptr || attr == nullptr || *attr == nullptr) {
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SceKernelSchedParam pparam{};
|
||||||
|
if (param->sched_priority <= 478) {
|
||||||
|
pparam.sched_priority = +2;
|
||||||
|
} else if (param->sched_priority >= 733) {
|
||||||
|
pparam.sched_priority = -2;
|
||||||
|
} else {
|
||||||
|
pparam.sched_priority = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = pthread_attr_setschedparam(&(*attr)->pth_attr, &pparam);
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
return SCE_OK;
|
||||||
|
}
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scePthreadAttrSetschedpolicy(ScePthreadAttr* attr, int policy) {
|
||||||
|
|
||||||
|
if (attr == nullptr || *attr == nullptr) {
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (policy!= SCHED_OTHER)
|
||||||
|
{
|
||||||
|
__debugbreak();//invest if policy is other and if winpthreadlibrary support it
|
||||||
|
}
|
||||||
|
|
||||||
|
(*attr)->policy = policy;
|
||||||
|
|
||||||
|
int result = pthread_attr_setschedpolicy(&(*attr)->pth_attr, policy);
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
return SCE_OK;
|
||||||
|
}
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
|
@ -0,0 +1,42 @@
|
||||||
|
#pragma once
|
||||||
|
#define _TIMESPEC_DEFINED
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include "../../../../types.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace HLE::Libs::LibKernel::ThreadManagement {
|
||||||
|
|
||||||
|
struct PthreadAttrInternal;
|
||||||
|
|
||||||
|
using SceKernelSchedParam = ::sched_param;
|
||||||
|
using ScePthreadAttr = PthreadAttrInternal*;
|
||||||
|
|
||||||
|
struct PthreadInternal {
|
||||||
|
u08 reserved[4096];
|
||||||
|
std::string name;
|
||||||
|
pthread_t pth;
|
||||||
|
ScePthreadAttr attr;
|
||||||
|
};
|
||||||
|
struct PthreadAttrInternal {
|
||||||
|
u08 reserved[64];
|
||||||
|
u64 affinity;
|
||||||
|
size_t guard_size;
|
||||||
|
int policy;
|
||||||
|
bool detached;
|
||||||
|
pthread_attr_t pth_attr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PThreadCxt {};
|
||||||
|
|
||||||
|
void Pthread_Init_Self_MainThread();
|
||||||
|
|
||||||
|
//HLE FUNCTIONS
|
||||||
|
int scePthreadAttrInit(ScePthreadAttr* attr);
|
||||||
|
int scePthreadAttrSetdetachstate(ScePthreadAttr* attr, int detachstate);
|
||||||
|
int scePthreadAttrSetinheritsched(ScePthreadAttr* attr, int inheritSched);
|
||||||
|
int scePthreadAttrSetschedparam(ScePthreadAttr* attr, const SceKernelSchedParam* param);
|
||||||
|
int scePthreadAttrSetschedpolicy(ScePthreadAttr* attr, int policy);
|
||||||
|
|
||||||
|
} // namespace HLE::Libs::LibKernel::ThreadManagement
|
|
@ -8,10 +8,7 @@ namespace HLE::Libs::LibC {
|
||||||
|
|
||||||
static void init_env() //every game/demo should probably
|
static void init_env() //every game/demo should probably
|
||||||
{
|
{
|
||||||
for(;;) {
|
//dummy no need atm
|
||||||
printf("__debugbreak\n");
|
|
||||||
}
|
|
||||||
//__debugbreak();//if we reach here it will be a great progress :D
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int __cxa_guard_acquire(u64* guard_object)
|
int __cxa_guard_acquire(u64* guard_object)
|
||||||
|
@ -39,7 +36,11 @@ namespace HLE::Libs::LibC {
|
||||||
|
|
||||||
}
|
}
|
||||||
static int atexit(void (*func)())
|
static int atexit(void (*func)())
|
||||||
{ return 0;
|
{
|
||||||
|
for (;;) {
|
||||||
|
printf("we reached here too!\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibC_Register(SymbolsResolver* sym)
|
void LibC_Register(SymbolsResolver* sym)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "../../Util/StringUtil.h"
|
#include "../../Util/StringUtil.h"
|
||||||
#include "Util/aerolib.h"
|
#include "Util/aerolib.h"
|
||||||
#include "Loader/SymbolsResolver.h"
|
#include "Loader/SymbolsResolver.h"
|
||||||
|
#include "HLE/Kernel/ThreadManagement.h"
|
||||||
|
|
||||||
|
|
||||||
constexpr bool debug_loader = true;
|
constexpr bool debug_loader = true;
|
||||||
|
@ -628,4 +629,27 @@ void Linker::Resolve(const std::string& name, int Symtype, Module* m, SymbolReco
|
||||||
__debugbreak();//oute edo mallon
|
__debugbreak();//oute edo mallon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
using exit_func_t = void (*)();
|
||||||
|
using entry_func_t = void (*)(EntryParams* params, exit_func_t atexit_func);
|
||||||
|
|
||||||
|
static void ProgramExitFunc() {
|
||||||
|
|
||||||
|
printf("exit function called\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void run_main_entry(u64 addr, EntryParams* params, exit_func_t exit_func) {
|
||||||
|
reinterpret_cast<entry_func_t>(addr)(params, exit_func);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Linker::Execute()
|
||||||
|
{
|
||||||
|
HLE::Libs::LibKernel::ThreadManagement::Pthread_Init_Self_MainThread();
|
||||||
|
EntryParams p{};
|
||||||
|
p.argc = 1;
|
||||||
|
p.argv[0] = "eboot.bin"; //hmm should be ok?
|
||||||
|
|
||||||
|
run_main_entry(m_modules.at(0)->elf->GetElfEntry()+m_modules.at(0)->base_virtual_addr, &p, ProgramExitFunc);
|
||||||
|
|
||||||
}
|
}
|
|
@ -7,6 +7,12 @@
|
||||||
struct DynamicModuleInfo;
|
struct DynamicModuleInfo;
|
||||||
class Linker;
|
class Linker;
|
||||||
|
|
||||||
|
struct EntryParams {
|
||||||
|
int argc;
|
||||||
|
u32 padding;
|
||||||
|
const char* argv[3];
|
||||||
|
};
|
||||||
|
|
||||||
/*this struct keeps neccesary info about loaded modules.Main executeable is included too as well*/
|
/*this struct keeps neccesary info about loaded modules.Main executeable is included too as well*/
|
||||||
struct Module
|
struct Module
|
||||||
{
|
{
|
||||||
|
@ -115,8 +121,9 @@ public:
|
||||||
SymbolsResolver* getHLESymbols() { return m_HLEsymbols; }
|
SymbolsResolver* getHLESymbols() { return m_HLEsymbols; }
|
||||||
void Relocate(Module* m);
|
void Relocate(Module* m);
|
||||||
void Resolve(const std::string& name, int Symtype, Module* m, SymbolRecord* return_info);
|
void Resolve(const std::string& name, int Symtype, Module* m, SymbolRecord* return_info);
|
||||||
|
void Execute();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const ModuleInfo* FindModule(const Module& m, const std::string& id);
|
const ModuleInfo* FindModule(const Module& m, const std::string& id);
|
||||||
const LibraryInfo* FindLibrary(const Module& program, const std::string& id);
|
const LibraryInfo* FindLibrary(const Module& program, const std::string& id);
|
||||||
|
|
||||||
|
|
|
@ -33,17 +33,18 @@
|
||||||
// Main code
|
// Main code
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if (argc == 1) {
|
/* if (argc == 1) {
|
||||||
printf("Usage: %s <elf or eboot.bin path>\n", argv[0]);
|
printf("Usage: %s <elf or eboot.bin path>\n", argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
logging::init(true);//init logging
|
logging::init(true);//init logging
|
||||||
const char* const path = argv[1]; //argument 1 is the path of self file to boot
|
const char* const path = argv[1]; // argument 1 is the path of self file to boot
|
||||||
auto* linker = Singleton<Linker>::Instance();
|
auto* linker = Singleton<Linker>::Instance();
|
||||||
HLE::Libs::Init_HLE_Libs(linker->getHLESymbols());
|
HLE::Libs::Init_HLE_Libs(linker->getHLESymbols());
|
||||||
auto *module =linker->LoadModule(path);//load main executable
|
auto *module =linker->LoadModule(path);//load main executable
|
||||||
|
|
||||||
|
linker->Execute();
|
||||||
#if 0
|
#if 0
|
||||||
// Setup SDL
|
// Setup SDL
|
||||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMEPAD) != 0)
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMEPAD) != 0)
|
||||||
|
|
|
@ -27,6 +27,8 @@ option(ZYDIS_BUILD_EXAMPLES "" OFF)
|
||||||
set(zydis_DIR ${CMAKE_CURRENT_SOURCE_DIR}/zydis)
|
set(zydis_DIR ${CMAKE_CURRENT_SOURCE_DIR}/zydis)
|
||||||
add_subdirectory(${zydis_DIR})
|
add_subdirectory(${zydis_DIR})
|
||||||
|
|
||||||
|
#========== winpthreads ======================
|
||||||
|
add_subdirectory(winpthread)
|
||||||
#=================== IMGUI ===================
|
#=================== IMGUI ===================
|
||||||
|
|
||||||
set(IMGUI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/imgui)
|
set(IMGUI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/imgui)
|
||||||
|
@ -56,6 +58,6 @@ find_package(OpenGL REQUIRED)
|
||||||
target_link_libraries(IMGUI PUBLIC ${OPENGL_LIBRARIES})
|
target_link_libraries(IMGUI PUBLIC ${OPENGL_LIBRARIES})
|
||||||
|
|
||||||
|
|
||||||
target_link_libraries(IMGUI PUBLIC SDL3-shared ${CMAKE_DL_LIBS} Zydis)
|
target_link_libraries(IMGUI PUBLIC SDL3-shared ${CMAKE_DL_LIBS} Zydis winpthread)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 125e7420ecd2b0d1847aef804f53e614fbc68253
|
Subproject commit 27556e098ecce54014ed1fc11c1e974ffdf4bc93
|
|
@ -1 +1 @@
|
||||||
Subproject commit de0757b578244e0bf7ac50007fb5e25fcc899c7c
|
Subproject commit 661b23edeb52d400cf5812e7330f14f05c072fab
|
|
@ -1 +1 @@
|
||||||
Subproject commit 4fab72b40e2972f5d56fc884ed5797446238844e
|
Subproject commit 52125a54a57a458e89bc61502010e964add3cdd5
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5018ef9677521983bfedb127901284432d1a05a2
|
Subproject commit 4904822db8770d04444add00a9e155568d3e8bd1
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5a6b6cafa8d4aee3e6d0dd16a2cae9169141c831
|
Subproject commit 76dfc7e7c0d3c69d3cdaa3399b63545235ccbb02
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 918de958b720c3ba7bc47f4988609c0109a0f75b
|
|
@ -1 +1 @@
|
||||||
Subproject commit d4c37ae7a9db989495eb66636a65d8d4ff69eb35
|
Subproject commit a6d0c713b71b5009634868389f0ff551871273d6
|
Loading…
Reference in New Issue