2020-12-05 13:08:24 +01:00
|
|
|
#pragma once
|
2016-04-14 01:09:41 +02:00
|
|
|
|
|
|
|
|
#include "PPUFunction.h"
|
|
|
|
|
#include "PPUCallback.h"
|
|
|
|
|
#include "ErrorCodes.h"
|
2018-09-25 22:34:45 +02:00
|
|
|
#include "Emu/Memory/vm_var.h"
|
2016-04-14 01:09:41 +02:00
|
|
|
|
2017-04-28 18:03:24 +02:00
|
|
|
// Helper function
|
2019-12-26 21:01:48 +01:00
|
|
|
constexpr const char* ppu_select_name(const char* name, u32 /*id*/)
|
2017-04-28 18:03:24 +02:00
|
|
|
{
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Helper function
|
2019-12-26 21:01:48 +01:00
|
|
|
constexpr const char* ppu_select_name(const char* /*name*/, const char* orig_name)
|
2017-04-28 18:03:24 +02:00
|
|
|
{
|
|
|
|
|
return orig_name;
|
|
|
|
|
}
|
2017-02-26 16:56:31 +01:00
|
|
|
|
2016-04-14 01:09:41 +02:00
|
|
|
// Generate FNID or VNID for given name
|
2021-09-06 09:33:44 +02:00
|
|
|
extern u32 ppu_generate_id(std::string_view name);
|
2016-04-14 01:09:41 +02:00
|
|
|
|
2018-02-09 15:49:37 +01:00
|
|
|
// Overload for REG_FNID, REG_VNID macro
|
2017-04-26 22:38:24 +02:00
|
|
|
constexpr u32 ppu_generate_id(u32 id)
|
|
|
|
|
{
|
|
|
|
|
return id;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-14 01:09:41 +02:00
|
|
|
// Flags set with REG_FUNC
|
2017-09-16 19:39:41 +02:00
|
|
|
enum ppu_static_module_flags : u32
|
2016-04-14 01:09:41 +02:00
|
|
|
{
|
2016-07-07 20:42:39 +02:00
|
|
|
MFF_FORCED_HLE = (1 << 0), // Always call HLE function
|
|
|
|
|
MFF_PERFECT = (1 << 1), // Indicates complete implementation and LLE interchangeability
|
2021-09-06 09:33:44 +02:00
|
|
|
MFF_HIDDEN = (1 << 2), // Invisible variable for internal use (TODO)
|
2016-04-14 01:09:41 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// HLE function information
|
|
|
|
|
struct ppu_static_function
|
|
|
|
|
{
|
|
|
|
|
const char* name;
|
|
|
|
|
u32 index; // Index for ppu_function_manager
|
|
|
|
|
u32 flags;
|
2017-09-16 19:39:41 +02:00
|
|
|
std::vector<const char*> args; // Arg names
|
2017-10-01 03:40:11 +02:00
|
|
|
const u32* export_addr;
|
2017-09-16 19:39:41 +02:00
|
|
|
|
|
|
|
|
ppu_static_function& flag(ppu_static_module_flags value)
|
|
|
|
|
{
|
|
|
|
|
flags |= value;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
2016-04-14 01:09:41 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// HLE variable information
|
|
|
|
|
struct ppu_static_variable
|
|
|
|
|
{
|
|
|
|
|
const char* name;
|
2021-03-08 21:41:23 +01:00
|
|
|
u32* var; // Pointer to variable address storage
|
2016-04-14 01:09:41 +02:00
|
|
|
void(*init)(); // Variable initialization function
|
|
|
|
|
u32 size;
|
|
|
|
|
u32 align;
|
2017-09-16 19:39:41 +02:00
|
|
|
u32 flags;
|
|
|
|
|
u32 addr;
|
2017-10-01 03:40:11 +02:00
|
|
|
const u32* export_addr;
|
2017-09-16 19:39:41 +02:00
|
|
|
|
|
|
|
|
ppu_static_variable& flag(ppu_static_module_flags value)
|
|
|
|
|
{
|
|
|
|
|
flags |= value;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
2016-04-14 01:09:41 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// HLE module information
|
|
|
|
|
class ppu_static_module final
|
|
|
|
|
{
|
2021-07-31 19:29:36 +02:00
|
|
|
std::vector<void(*)(ppu_static_module*)> m_on_init;
|
|
|
|
|
|
2016-04-14 01:09:41 +02:00
|
|
|
public:
|
|
|
|
|
const std::string name;
|
|
|
|
|
|
2021-04-19 13:22:03 +02:00
|
|
|
std::unordered_map<u32, ppu_static_function, value_hash<u32>> functions{};
|
|
|
|
|
std::unordered_map<u32, ppu_static_variable, value_hash<u32>> variables{};
|
2016-04-14 01:09:41 +02:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
ppu_static_module(const char* name);
|
|
|
|
|
|
|
|
|
|
ppu_static_module(const char* name, void(*init)())
|
|
|
|
|
: ppu_static_module(name)
|
|
|
|
|
{
|
|
|
|
|
init();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ppu_static_module(const char* name, void(*init)(ppu_static_module* _this))
|
|
|
|
|
: ppu_static_module(name)
|
|
|
|
|
{
|
|
|
|
|
init(this);
|
|
|
|
|
}
|
2021-07-31 19:29:36 +02:00
|
|
|
|
|
|
|
|
void add_init_func(void(*func)(ppu_static_module*));
|
|
|
|
|
|
|
|
|
|
void initialize();
|
2016-04-14 01:09:41 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class ppu_module_manager final
|
|
|
|
|
{
|
|
|
|
|
friend class ppu_static_module;
|
|
|
|
|
|
2020-05-06 17:18:30 +02:00
|
|
|
static void register_module(ppu_static_module*);
|
2016-04-14 01:09:41 +02:00
|
|
|
|
2020-05-06 17:18:30 +02:00
|
|
|
static ppu_static_function& access_static_function(const char* _module, u32 fnid);
|
2016-04-14 01:09:41 +02:00
|
|
|
|
2020-05-06 17:18:30 +02:00
|
|
|
static ppu_static_variable& access_static_variable(const char* _module, u32 vnid);
|
2016-04-14 01:09:41 +02:00
|
|
|
|
2017-10-01 03:40:11 +02:00
|
|
|
// Global variable for each registered function
|
2018-10-06 16:09:09 +02:00
|
|
|
template <auto* Func>
|
2017-10-01 03:40:11 +02:00
|
|
|
struct registered
|
|
|
|
|
{
|
|
|
|
|
static ppu_static_function* info;
|
|
|
|
|
};
|
|
|
|
|
|
2016-04-14 01:09:41 +02:00
|
|
|
public:
|
2016-04-27 00:27:24 +02:00
|
|
|
static const ppu_static_module* get_module(const std::string& name);
|
2016-04-14 01:09:41 +02:00
|
|
|
|
2021-07-31 19:29:36 +02:00
|
|
|
static void initialize_modules();
|
|
|
|
|
|
2018-10-06 16:09:09 +02:00
|
|
|
template <auto* Func>
|
2021-12-30 17:39:18 +01:00
|
|
|
static auto& register_static_function(const char* _module, const char* name, ppu_intrp_func_t func, u32 fnid)
|
2016-04-14 01:09:41 +02:00
|
|
|
{
|
2020-05-06 17:18:30 +02:00
|
|
|
auto& info = access_static_function(_module, fnid);
|
2016-04-14 01:09:41 +02:00
|
|
|
|
|
|
|
|
info.name = name;
|
2018-10-06 16:09:09 +02:00
|
|
|
info.index = ppu_function_manager::register_function<decltype(Func), Func>(func);
|
2017-02-13 12:54:58 +01:00
|
|
|
info.flags = 0;
|
|
|
|
|
|
2018-10-06 16:09:09 +02:00
|
|
|
registered<Func>::info = &info;
|
2017-10-01 03:40:11 +02:00
|
|
|
|
2017-02-13 12:54:58 +01:00
|
|
|
return info;
|
2016-04-14 01:09:41 +02:00
|
|
|
}
|
|
|
|
|
|
2018-10-06 16:09:09 +02:00
|
|
|
template <auto* Func>
|
2017-10-01 03:40:11 +02:00
|
|
|
static auto& find_static_function()
|
|
|
|
|
{
|
2018-10-06 16:09:09 +02:00
|
|
|
return *registered<Func>::info;
|
2017-10-01 03:40:11 +02:00
|
|
|
}
|
|
|
|
|
|
2018-10-06 16:09:09 +02:00
|
|
|
template <auto* Var>
|
2020-05-06 17:18:30 +02:00
|
|
|
static auto& register_static_variable(const char* _module, const char* name, u32 vnid)
|
2016-04-14 01:09:41 +02:00
|
|
|
{
|
2018-10-06 16:09:09 +02:00
|
|
|
using gvar = std::decay_t<decltype(*Var)>;
|
|
|
|
|
|
|
|
|
|
static_assert(std::is_same<u32, typename gvar::addr_type>::value, "Static variable registration: vm::gvar<T> expected");
|
2016-04-14 01:09:41 +02:00
|
|
|
|
2020-05-06 17:18:30 +02:00
|
|
|
auto& info = access_static_variable(_module, vnid);
|
2016-04-14 01:09:41 +02:00
|
|
|
|
|
|
|
|
info.name = name;
|
2021-03-08 21:41:23 +01:00
|
|
|
info.var = &Var->raw();
|
2017-02-13 12:54:58 +01:00
|
|
|
info.init = [] {};
|
2019-09-14 23:15:28 +02:00
|
|
|
info.size = gvar::alloc_size;
|
|
|
|
|
info.align = gvar::alloc_align;
|
2017-09-16 19:39:41 +02:00
|
|
|
info.flags = 0;
|
|
|
|
|
info.addr = 0;
|
2017-02-13 12:54:58 +01:00
|
|
|
|
|
|
|
|
return info;
|
2016-04-14 01:09:41 +02:00
|
|
|
}
|
|
|
|
|
|
2020-08-06 12:34:08 +02:00
|
|
|
// We need this to deal with the enumeration over all ppu_static_modules that happens in ppu_initialize_modules
|
|
|
|
|
static const std::unordered_map<std::string, ppu_static_module*>& get()
|
2017-04-22 16:58:40 +02:00
|
|
|
{
|
2020-08-06 12:34:08 +02:00
|
|
|
return s_module_map;
|
2017-04-22 16:58:40 +02:00
|
|
|
}
|
|
|
|
|
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module cellAdec;
|
|
|
|
|
static const ppu_static_module cellAtrac;
|
|
|
|
|
static const ppu_static_module cellAtracMulti;
|
|
|
|
|
static const ppu_static_module cellAudio;
|
|
|
|
|
static const ppu_static_module cellAvconfExt;
|
2020-02-20 18:34:09 +01:00
|
|
|
static const ppu_static_module cellAuthDialogUtility;
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module cellBGDL;
|
|
|
|
|
static const ppu_static_module cellCamera;
|
|
|
|
|
static const ppu_static_module cellCelp8Enc;
|
|
|
|
|
static const ppu_static_module cellCelpEnc;
|
2017-03-25 15:25:24 +01:00
|
|
|
static const ppu_static_module cellCrossController;
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module cellDaisy;
|
|
|
|
|
static const ppu_static_module cellDmux;
|
2019-03-24 09:29:49 +01:00
|
|
|
static const ppu_static_module cellDtcpIpUtility;
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module cellFiber;
|
|
|
|
|
static const ppu_static_module cellFont;
|
|
|
|
|
static const ppu_static_module cellFontFT;
|
2017-02-13 03:46:02 +01:00
|
|
|
static const ppu_static_module cell_FreeType2;
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module cellFs;
|
|
|
|
|
static const ppu_static_module cellGame;
|
|
|
|
|
static const ppu_static_module cellGameExec;
|
|
|
|
|
static const ppu_static_module cellGcmSys;
|
|
|
|
|
static const ppu_static_module cellGem;
|
|
|
|
|
static const ppu_static_module cellGifDec;
|
|
|
|
|
static const ppu_static_module cellHttp;
|
|
|
|
|
static const ppu_static_module cellHttps;
|
|
|
|
|
static const ppu_static_module cellHttpUtil;
|
|
|
|
|
static const ppu_static_module cellImeJp;
|
|
|
|
|
static const ppu_static_module cellJpgDec;
|
|
|
|
|
static const ppu_static_module cellJpgEnc;
|
|
|
|
|
static const ppu_static_module cellKey2char;
|
|
|
|
|
static const ppu_static_module cellL10n;
|
2017-04-07 14:48:59 +02:00
|
|
|
static const ppu_static_module cellLibprof;
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module cellMic;
|
|
|
|
|
static const ppu_static_module cellMusic;
|
|
|
|
|
static const ppu_static_module cellMusicDecode;
|
|
|
|
|
static const ppu_static_module cellMusicExport;
|
2019-03-23 23:09:41 +01:00
|
|
|
static const ppu_static_module cellNetAoi;
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module cellNetCtl;
|
|
|
|
|
static const ppu_static_module cellOskDialog;
|
|
|
|
|
static const ppu_static_module cellOvis;
|
|
|
|
|
static const ppu_static_module cellPamf;
|
2019-03-24 14:09:08 +01:00
|
|
|
static const ppu_static_module cellPesmUtility;
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module cellPhotoDecode;
|
|
|
|
|
static const ppu_static_module cellPhotoExport;
|
|
|
|
|
static const ppu_static_module cellPhotoImportUtil;
|
|
|
|
|
static const ppu_static_module cellPngDec;
|
|
|
|
|
static const ppu_static_module cellPngEnc;
|
|
|
|
|
static const ppu_static_module cellPrint;
|
|
|
|
|
static const ppu_static_module cellRec;
|
|
|
|
|
static const ppu_static_module cellRemotePlay;
|
|
|
|
|
static const ppu_static_module cellResc;
|
|
|
|
|
static const ppu_static_module cellRtc;
|
2017-04-19 20:24:52 +02:00
|
|
|
static const ppu_static_module cellRtcAlarm;
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module cellRudp;
|
|
|
|
|
static const ppu_static_module cellSail;
|
|
|
|
|
static const ppu_static_module cellSailRec;
|
|
|
|
|
static const ppu_static_module cellSaveData;
|
|
|
|
|
static const ppu_static_module cellMinisSaveData;
|
|
|
|
|
static const ppu_static_module cellScreenShot;
|
|
|
|
|
static const ppu_static_module cellSearch;
|
|
|
|
|
static const ppu_static_module cellSheap;
|
|
|
|
|
static const ppu_static_module cellSpudll;
|
|
|
|
|
static const ppu_static_module cellSpurs;
|
|
|
|
|
static const ppu_static_module cellSpursJq;
|
|
|
|
|
static const ppu_static_module cellSsl;
|
2017-07-21 17:41:11 +02:00
|
|
|
static const ppu_static_module cellSubDisplay;
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module cellSync;
|
|
|
|
|
static const ppu_static_module cellSync2;
|
|
|
|
|
static const ppu_static_module cellSysconf;
|
|
|
|
|
static const ppu_static_module cellSysmodule;
|
|
|
|
|
static const ppu_static_module cellSysutil;
|
|
|
|
|
static const ppu_static_module cellSysutilAp;
|
|
|
|
|
static const ppu_static_module cellSysutilAvc2;
|
2019-03-24 20:59:18 +01:00
|
|
|
static const ppu_static_module cellSysutilAvcExt;
|
2017-03-25 15:25:24 +01:00
|
|
|
static const ppu_static_module cellSysutilNpEula;
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module cellSysutilMisc;
|
|
|
|
|
static const ppu_static_module cellUsbd;
|
|
|
|
|
static const ppu_static_module cellUsbPspcm;
|
|
|
|
|
static const ppu_static_module cellUserInfo;
|
|
|
|
|
static const ppu_static_module cellVdec;
|
|
|
|
|
static const ppu_static_module cellVideoExport;
|
2019-03-24 16:04:22 +01:00
|
|
|
static const ppu_static_module cellVideoPlayerUtility;
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module cellVideoUpload;
|
|
|
|
|
static const ppu_static_module cellVoice;
|
|
|
|
|
static const ppu_static_module cellVpost;
|
2019-03-25 20:32:03 +01:00
|
|
|
static const ppu_static_module libad_async;
|
|
|
|
|
static const ppu_static_module libad_core;
|
2021-07-17 13:08:21 +02:00
|
|
|
static const ppu_static_module libfs_utility_init;
|
2017-03-25 15:25:24 +01:00
|
|
|
static const ppu_static_module libmedi;
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module libmixer;
|
|
|
|
|
static const ppu_static_module libsnd3;
|
|
|
|
|
static const ppu_static_module libsynth2;
|
|
|
|
|
static const ppu_static_module sceNp;
|
|
|
|
|
static const ppu_static_module sceNp2;
|
|
|
|
|
static const ppu_static_module sceNpClans;
|
|
|
|
|
static const ppu_static_module sceNpCommerce2;
|
2018-02-03 14:07:41 +01:00
|
|
|
static const ppu_static_module sceNpMatchingInt;
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module sceNpSns;
|
|
|
|
|
static const ppu_static_module sceNpTrophy;
|
|
|
|
|
static const ppu_static_module sceNpTus;
|
|
|
|
|
static const ppu_static_module sceNpUtil;
|
2021-03-08 16:28:07 +01:00
|
|
|
static const ppu_static_module sys_crashdump;
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module sys_io;
|
2017-09-25 17:52:34 +02:00
|
|
|
static const ppu_static_module sys_net;
|
2016-04-14 01:09:41 +02:00
|
|
|
static const ppu_static_module sysPrxForUser;
|
|
|
|
|
static const ppu_static_module sys_libc;
|
|
|
|
|
static const ppu_static_module sys_lv2dbg;
|
2018-10-26 12:08:45 +02:00
|
|
|
static const ppu_static_module static_hle;
|
2020-08-06 12:34:08 +02:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
inline static std::unordered_map<std::string, ppu_static_module*> s_module_map;
|
2016-04-14 01:09:41 +02:00
|
|
|
};
|
|
|
|
|
|
2018-10-06 16:09:09 +02:00
|
|
|
template <auto* Func>
|
|
|
|
|
ppu_static_function* ppu_module_manager::registered<Func>::info = nullptr;
|
2017-10-01 03:40:11 +02:00
|
|
|
|
2016-04-14 01:09:41 +02:00
|
|
|
// Call specified function directly if LLE is not available, call LLE equivalent in callback style otherwise
|
2018-10-06 16:09:09 +02:00
|
|
|
template <auto* Func, typename... Args, typename RT = std::invoke_result_t<decltype(Func), ppu_thread&, Args...>>
|
|
|
|
|
inline RT ppu_execute(ppu_thread& ppu, Args... args)
|
2016-04-14 01:09:41 +02:00
|
|
|
{
|
2018-10-06 16:09:09 +02:00
|
|
|
vm::ptr<RT(Args...)> func = vm::cast(*ppu_module_manager::find_static_function<Func>().export_addr);
|
|
|
|
|
return func(ppu, args...);
|
2016-04-14 01:09:41 +02:00
|
|
|
}
|
|
|
|
|
|
2021-09-06 09:33:44 +02:00
|
|
|
#define BIND_FUNC_WITH_BLR(func) BIND_FUNC(func, ppu.cia = static_cast<u32>(ppu.lr) & ~3)
|
|
|
|
|
|
|
|
|
|
#define REG_FNID(_module, nid, func) ppu_module_manager::register_static_function<&func>(#_module, ppu_select_name(#func, nid), BIND_FUNC_WITH_BLR(func), ppu_generate_id(nid))
|
2016-04-14 01:09:41 +02:00
|
|
|
|
2020-05-06 17:18:30 +02:00
|
|
|
#define REG_FUNC(_module, func) REG_FNID(_module, #func, func)
|
2016-04-14 01:09:41 +02:00
|
|
|
|
2020-05-06 17:18:30 +02:00
|
|
|
#define REG_VNID(_module, nid, var) ppu_module_manager::register_static_variable<&var>(#_module, ppu_select_name(#var, nid), ppu_generate_id(nid))
|
2016-04-14 01:09:41 +02:00
|
|
|
|
2020-05-06 17:18:30 +02:00
|
|
|
#define REG_VAR(_module, var) REG_VNID(_module, #var, var)
|
2016-04-14 01:09:41 +02:00
|
|
|
|
2021-09-06 09:33:44 +02:00
|
|
|
#define REG_HIDDEN_FUNC(func) ppu_function_manager::register_function<decltype(&func), &func>(BIND_FUNC_WITH_BLR(func))
|
|
|
|
|
|
|
|
|
|
#define REG_HIDDEN_FUNC_PURE(func) ppu_function_manager::register_function<decltype(&func), &func>(func)
|
|
|
|
|
|
2021-08-01 07:19:58 +02:00
|
|
|
#define REINIT_FUNC(func) (ppu_module_manager::find_static_function<&func>().flags = 0, ppu_module_manager::find_static_function<&func>())
|
2021-07-31 19:29:36 +02:00
|
|
|
|
2020-05-06 17:18:30 +02:00
|
|
|
#define UNIMPLEMENTED_FUNC(_module) _module.todo("%s()", __func__)
|