Fix HLE LWMutex setting - Implement dynamic initialization of HLE functions

This commit is contained in:
Eladash 2021-07-31 20:29:36 +03:00 committed by Ivan
parent 6527eef655
commit a0c1b250b6
5 changed files with 70 additions and 18 deletions

View file

@ -168,8 +168,8 @@ error_code sysPs2Disc_BB7CD1AE()
return CELL_OK;
}
extern void sysPrxForUser_sys_lwmutex_init();
extern void sysPrxForUser_sys_lwcond_init();
extern void sysPrxForUser_sys_lwmutex_init(ppu_static_module*);
extern void sysPrxForUser_sys_lwcond_init(ppu_static_module*);
extern void sysPrxForUser_sys_ppu_thread_init();
extern void sysPrxForUser_sys_prx_init();
extern void sysPrxForUser_sys_heap_init();
@ -181,7 +181,7 @@ extern void sysPrxForUser_sys_game_init();
extern void sysPrxForUser_sys_libc_init();
extern void sysPrxForUser_sys_rsxaudio_init();
DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", []()
DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", [](ppu_static_module* _this)
{
static ppu_static_module cellGamePs1Emu("cellGamePs1Emu", []()
{
@ -217,8 +217,8 @@ DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", []()
REG_FNID(sysPs2Disc, 0xBB7CD1AE, sysPs2Disc_BB7CD1AE);
});
sysPrxForUser_sys_lwmutex_init();
sysPrxForUser_sys_lwcond_init();
sysPrxForUser_sys_lwmutex_init(_this);
sysPrxForUser_sys_lwcond_init(_this);
sysPrxForUser_sys_ppu_thread_init();
sysPrxForUser_sys_prx_init();
sysPrxForUser_sys_heap_init();

View file

@ -369,12 +369,22 @@ error_code sys_lwcond_wait(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond, u64 ti
fmt::throw_exception("Unexpected syscall result (lwcond=*0x%x, result=0x%x)", lwcond, +res);
}
void sysPrxForUser_sys_lwcond_init()
void sysPrxForUser_sys_lwcond_init(ppu_static_module* _this)
{
REG_FUNC(sysPrxForUser, sys_lwcond_create).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
REG_FUNC(sysPrxForUser, sys_lwcond_destroy).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
REG_FUNC(sysPrxForUser, sys_lwcond_signal).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
REG_FUNC(sysPrxForUser, sys_lwcond_signal_all).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
REG_FUNC(sysPrxForUser, sys_lwcond_signal_to).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
REG_FUNC(sysPrxForUser, sys_lwcond_wait).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
REG_FUNC(sysPrxForUser, sys_lwcond_create);
REG_FUNC(sysPrxForUser, sys_lwcond_destroy);
REG_FUNC(sysPrxForUser, sys_lwcond_signal);
REG_FUNC(sysPrxForUser, sys_lwcond_signal_all);
REG_FUNC(sysPrxForUser, sys_lwcond_signal_to);
REG_FUNC(sysPrxForUser, sys_lwcond_wait);
_this->add_init_func([](ppu_static_module*)
{
ACCESS_FUNC(sys_lwcond_create).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
ACCESS_FUNC(sys_lwcond_destroy).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
ACCESS_FUNC(sys_lwcond_signal).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
ACCESS_FUNC(sys_lwcond_signal_all).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
ACCESS_FUNC(sys_lwcond_signal_to).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
ACCESS_FUNC(sys_lwcond_wait).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
});
}

View file

@ -379,11 +379,20 @@ error_code sys_lwmutex_unlock(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
return CELL_OK;
}
void sysPrxForUser_sys_lwmutex_init()
void sysPrxForUser_sys_lwmutex_init(ppu_static_module* _this)
{
REG_FUNC(sysPrxForUser, sys_lwmutex_create).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
REG_FUNC(sysPrxForUser, sys_lwmutex_destroy).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
REG_FUNC(sysPrxForUser, sys_lwmutex_lock).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
REG_FUNC(sysPrxForUser, sys_lwmutex_trylock).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
REG_FUNC(sysPrxForUser, sys_lwmutex_unlock).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
REG_FUNC(sysPrxForUser, sys_lwmutex_create);
REG_FUNC(sysPrxForUser, sys_lwmutex_destroy);
REG_FUNC(sysPrxForUser, sys_lwmutex_lock);
REG_FUNC(sysPrxForUser, sys_lwmutex_trylock);
REG_FUNC(sysPrxForUser, sys_lwmutex_unlock);
_this->add_init_func([](ppu_static_module*)
{
ACCESS_FUNC(sys_lwmutex_create).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
ACCESS_FUNC(sys_lwmutex_destroy).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
ACCESS_FUNC(sys_lwmutex_lock).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
ACCESS_FUNC(sys_lwmutex_trylock).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
ACCESS_FUNC(sys_lwmutex_unlock).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT);
});
}

View file

@ -60,6 +60,19 @@ ppu_static_module::ppu_static_module(const char* name)
ppu_module_manager::register_module(this);
}
void ppu_static_module::add_init_func(void(*func)(ppu_static_module*))
{
m_on_init.emplace_back(func);
}
void ppu_static_module::initialize()
{
for (auto func : m_on_init)
{
func(this);
}
}
void ppu_module_manager::register_module(ppu_static_module* _module)
{
ppu_module_manager::s_module_map.emplace(_module->name, _module);
@ -96,6 +109,14 @@ const ppu_static_module* ppu_module_manager::get_module(const std::string& name)
return found != map.end() ? found->second : nullptr;
}
void ppu_module_manager::initialize_modules()
{
for (auto& _module : s_module_map)
{
_module.second->initialize();
}
}
// Global linkage information
struct ppu_linkage_info
{
@ -136,6 +157,8 @@ static void ppu_initialize_modules(ppu_linkage_info* link)
return;
}
ppu_module_manager::initialize_modules();
const std::initializer_list<const ppu_static_module*> registered
{
&ppu_module_manager::cellAdec,

View file

@ -72,6 +72,8 @@ struct ppu_static_variable
// HLE module information
class ppu_static_module final
{
std::vector<void(*)(ppu_static_module*)> m_on_init;
public:
const std::string name;
@ -92,6 +94,10 @@ public:
{
init(this);
}
void add_init_func(void(*func)(ppu_static_module*));
void initialize();
};
class ppu_module_manager final
@ -114,6 +120,8 @@ class ppu_module_manager final
public:
static const ppu_static_module* get_module(const std::string& name);
static void initialize_modules();
template <auto* Func>
static auto& register_static_function(const char* _module, const char* name, ppu_function_t func, u32 fnid)
{
@ -293,4 +301,6 @@ inline RT ppu_execute(ppu_thread& ppu, Args... args)
#define REG_VAR(_module, var) REG_VNID(_module, #var, var)
#define ACCESS_FUNC(func) ppu_module_manager::find_static_function<&func>()
#define UNIMPLEMENTED_FUNC(_module) _module.todo("%s()", __func__)