HLE: Bind guest PPC/IOSU variables to lifetime of their module

SysAllocator<> would allocate at Cemu boot and then never release memory.
Now we have CafeStaticVar<owner, type, count> which is explicitly allocated/deallocated via the owner and can be tied to COS/IOSU module lifetime. This also works as an automatic reset when relaunching emulation.
This commit is contained in:
Exzap committed 2026-10-25 08:08:07 +01:00
1 parent d46466cd51
commit bb28394ce1
65 files changed
+804 -234

No files matched your search

+2 -4
View File
@@ -1,6 +1,5 @@
#include "Cafe/OS/common/OSCommon.h"
#include "WindowSystem.h"
#include "Cafe/OS/libs/gx2/GX2.h"
#include "Cafe/GameProfile/GameProfile.h"
#include "Cafe/HW/Espresso/Interpreter/PPCInterpreterInternal.h"
#include "Cafe/HW/Espresso/Recompiler/PPCRecompiler.h"
@@ -27,6 +26,7 @@
#include "GamePatch.h"
#include "HW/Espresso/Debugger/GDBStub.h"
#include "Common/CafeStaticVar.h"
#include "Cafe/IOSU/legacy/iosu_ioctl.h"
#include "Cafe/IOSU/legacy/iosu_act.h"
#include "Cafe/IOSU/legacy/iosu_fpd.h"
@@ -624,9 +624,6 @@ namespace CafeSystem
cemuLog_log(LogType::Force, "Used CPU extensions: {}", g_CPUFeatures.GetCommaSeparatedExtensionList());
// misc systems
rplSymbolStorage_init();
// allocate memory for all SysAllocators
// must happen before COS module init, but also before iosu::kernel::Initialize()
SysAllocatorContainer::GetInstance().Initialize();
// init IOSU modules
for(auto& module : s_iosuModules)
module->SystemLaunch();
@@ -664,6 +661,7 @@ namespace CafeSystem
// shutdown IOSU modules
for(auto it = s_iosuModules.rbegin(); it != s_iosuModules.rend(); ++it)
(*it)->SystemExit();
cemu_assert_debug(!IOSUStaticData::HasAnyAllocations()); // check for leak
s_initialized = false;
}
+2 -1
View File
@@ -5,7 +5,7 @@
#include "Cafe/HW/Espresso/Recompiler/PPCRecompiler.h"
#include "Cemu/ExpressionParser/ExpressionParser.h"
#include "Cafe/OS/libs/coreinit/coreinit.h"
#include "Cafe/OS/libs/coreinit/coreinit_Thread.h"
#include "OS/RPL/rpl.h"
#include "util/helpers/helpers.h"
@@ -792,3 +792,4 @@ bool debugger_getOptionLogOnlyMemoryBreakpoints()
{
return s_debuggerState.logOnlyMemoryBreakpoints;
}
+1
View File
@@ -60,6 +60,7 @@ void _PPCCore_callbackExit(PPCInterpreter_t* hCPU)
PPCInterpreter_t* PPCCore_executeCallbackInternal(uint32 functionMPTR)
{
cemu_assert_debug(PPCInterpreter_getCurrentInstance()); // PPC callbacks can be only called from the dedicated PPC scheduler threads
cemu_assert_debug(functionMPTR != 0);
PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance();
// remember LR and instruction pointer
+3 -2
View File
@@ -112,7 +112,8 @@ MMURange mmuRange_LOW0 { 0x00010000, 0x000F0000, MMU_MEM_AREA_ID::CODE_LOW0,
MMURange mmuRange_TRAMPOLINE_AREA { 0x00E00000, 0x00200000, MMU_MEM_AREA_ID::CODE_TRAMPOLINE, "TRAMPOLINE_AREA" }; // code area for trampolines and imports
MMURange mmuRange_CODECAVE { 0x01800000, 0x00400000, MMU_MEM_AREA_ID::CODE_CAVE, "CODECAVE" }; // code cave area (4MiB)
MMURange mmuRange_TEXT_AREA { 0x02000000, 0x0C000000, MMU_MEM_AREA_ID::CODE_MAIN, "TEXT_AREA" }; // module text sections go here (0x02000000 to 0x10000000, 224MiB)
MMURange mmuRange_CEMU_AREA { 0x0E000000, 0x02000000, MMU_MEM_AREA_ID::CEMU_PRIVATE, "CEMU_AREA", MMURange::MFLAG::FLAG_MAP_EARLY }; // Cemu-only, 32MiB. Should be allocated early for SysAllocator
MMURange mmuRange_CEMU_AREA { 0x0E000000, 0x01C00000, MMU_MEM_AREA_ID::CEMU_PRIVATE, "CEMU_AREA", MMURange::MFLAG::FLAG_MAP_EARLY }; // Cemu-only, 28MiB
MMURange mmuRange_IOSU_AREA { 0x0FC00000, 0x00400000, MMU_MEM_AREA_ID::IOSU_PRIVATE, "IOSU_AREA", MMURange::MFLAG::FLAG_MAP_EARLY }; // Cemu-only, 4MiB
MMURange mmuRange_MEM2 { 0x10000000, 0x40000000, MMU_MEM_AREA_ID::MEM2_DATA, "MEM2" }; // main memory area (1GB)
MMURange mmuRange_OVERLAY_AREA { 0xA0000000, 0x1C000000, MMU_MEM_AREA_ID::OVERLAY, "OVERLAY_AREA", MMURange::MFLAG::FLAG_OPTIONAL }; // has to be requested, 448MiB
MMURange mmuRange_FGBUCKET { 0xE0000000, 0x04000000, MMU_MEM_AREA_ID::FGBUCKET, "FGBUCKET" }; // foreground bucket (64MiB)
@@ -139,7 +140,7 @@ void memory_init()
}
for (auto& itr : g_mmuRanges)
{
if (itr->isMappedEarly())
if (itr->isMappedEarly() && !itr->isMapped())
itr->mapMem();
}
}
+2
View File
@@ -39,6 +39,7 @@ enum class MMU_MEM_AREA_ID
CPU_PER_CORE,
CEMU_PRIVATE,
IOSU_PRIVATE,
};
struct MMURange
@@ -125,6 +126,7 @@ extern MMURange mmuRange_CODECAVE;
extern MMURange mmuRange_TEXT_AREA;
extern MMURange mmuRange_MEM2;
extern MMURange mmuRange_CEMU_AREA;
extern MMURange mmuRange_IOSU_AREA;
extern MMURange mmuRange_OVERLAY_AREA;
extern MMURange mmuRange_FGBUCKET;
extern MMURange mmuRange_TILINGAPERTURE;
+7 -2
View File
@@ -1,9 +1,10 @@
#include <util/helpers/helpers.h>
#include "util/helpers/helpers.h"
#include "iosu_odm.h"
#include "config/ActiveSettings.h"
#include "Common/FileStream.h"
#include "util/helpers/Semaphore.h"
#include "../kernel/iosu_kernel.h"
#include "Common/CafeStaticVar.h"
namespace iosu
{
@@ -18,7 +19,8 @@ namespace iosu
std::atomic_bool s_threadInitialized{ false };
IOSMsgQueueId s_msgQueueId;
SysAllocator<iosu::kernel::IOSMessage, 128> _s_msgBuffer;
constinit IOSUStaticData s_odmStaticData;
CafeStaticVar<iosu::kernel::IOSMessage, 128> _s_msgBuffer{s_odmStaticData};
enum class ODM_CMD_OPERATION_TYPE
{
@@ -139,6 +141,7 @@ namespace iosu
{
if (s_isRunning.exchange(true))
return;
s_odmStaticData.Allocate();
s_threadInitialized = false;
s_requestStop = false;
s_serviceThread = std::thread(&ODMServiceThread);
@@ -152,6 +155,8 @@ namespace iosu
s_requestStop = true;
IOS_SendMessage(s_msgQueueId, 0, 0);
s_serviceThread.join();
IOS_DestroyMessageQueue(s_msgQueueId);
s_odmStaticData.Deallocate();
}
}
}
+7 -1
View File
@@ -1,3 +1,4 @@
#include "Common/CafeStaticVar.h"
#include "iosu_ccr_nfc.h"
#include "Cafe/IOSU/kernel/iosu_kernel.h"
#include "util/crypto/aes128.h"
@@ -9,7 +10,8 @@ namespace iosu
namespace ccr_nfc
{
IOSMsgQueueId sCCRNFCMsgQueue;
SysAllocator<iosu::kernel::IOSMessage, 0x20> sCCRNFCMsgQueueMsgBuffer;
constinit IOSUStaticData s_ccrNfcStaticData;
CafeStaticVar<iosu::kernel::IOSMessage, 0x20> sCCRNFCMsgQueueMsgBuffer{s_ccrNfcStaticData};
std::thread sCCRNFCThread;
constexpr uint8 sNfcKey[] = { 0xC1, 0x2B, 0x07, 0x10, 0xD7, 0x2C, 0xEB, 0x5D, 0x43, 0x49, 0xB7, 0x43, 0xE3, 0xCA, 0xD2, 0x24 };
@@ -374,6 +376,8 @@ namespace iosu
{
void SystemLaunch() override
{
s_ccrNfcStaticData.Allocate();
sCCRNFCMsgQueue = iosu::kernel::IOS_CreateMessageQueue(sCCRNFCMsgQueueMsgBuffer.GetPtr(), sCCRNFCMsgQueueMsgBuffer.GetCount());
cemu_assert(!IOS_ResultIsError(static_cast<IOS_ERROR>(sCCRNFCMsgQueue)));
@@ -395,6 +399,8 @@ namespace iosu
iosu::kernel::IOS_DestroyMessageQueue(sCCRNFCMsgQueue);
sCCRNFCMsgQueue = -1;
s_ccrNfcStaticData.Deallocate();
}
} sIOSUModuleCCRNFC;
+6 -3
View File
@@ -1,3 +1,4 @@
#include "Common/CafeStaticVar.h"
#include "fsa_types.h"
#include "iosu_fsa.h"
#include "Cafe/IOSU/kernel/iosu_kernel.h"
@@ -7,8 +8,6 @@
#include "Cafe/OS/libs/coreinit/coreinit_FS.h" // get rid of this dependency, requires reworking some of the IPC stuff. See locations where we use coreinit::FSCmdBlockBody_t
#include "Cafe/HW/Latte/Core/LatteBufferCache.h" // also remove this dependency
#include "Cafe/HW/MMU/MMU.h"
using namespace iosu::kernel;
namespace iosu
@@ -16,7 +15,8 @@ namespace iosu
namespace fsa
{
IOSMsgQueueId sFSAIoMsgQueue;
SysAllocator<iosu::kernel::IOSMessage, 352> _m_sFSAIoMsgQueueMsgBuffer;
constinit IOSUStaticData s_fsaStaticData;
CafeStaticVar<iosu::kernel::IOSMessage, 352> _m_sFSAIoMsgQueueMsgBuffer{s_fsaStaticData};
std::thread sFSAIoThread;
struct FSAClient // IOSU's counterpart to the coreinit FSClient struct
@@ -888,6 +888,7 @@ namespace iosu
void Initialize()
{
s_fsaStaticData.Allocate();
for (auto& it : sFSAClientArray)
it.ReleaseAndCleanup();
sFSAIoMsgQueue = (IOSMsgQueueId)IOS_CreateMessageQueue(_m_sFSAIoMsgQueueMsgBuffer.GetPtr(), _m_sFSAIoMsgQueueMsgBuffer.GetCount());
@@ -901,6 +902,8 @@ namespace iosu
{
IOS_SendMessage(sFSAIoMsgQueue, 0, 0);
sFSAIoThread.join();
IOS_DestroyMessageQueue(sFSAIoMsgQueue);
s_fsaStaticData.Deallocate();
}
} // namespace fsa
} // namespace iosu
+7 -1
View File
@@ -3,12 +3,14 @@
#include "util/helpers/helpers.h"
#include "Cafe/OS/libs/coreinit/coreinit_IPC.h"
#include "util/highresolutiontimer/HighResolutionTimer.h"
#include "Common/CafeStaticVar.h"
namespace iosu
{
namespace kernel
{
std::mutex sInternalMutex;
constinit IOSUStaticData s_kernelStaticData;
void IOS_DestroyResourceManagerForQueueId(IOSMsgQueueId msgQueueId);
void _IPCDestroyAllHandlesForMsgQueue(IOSMsgQueueId msgQueueId);
@@ -66,6 +68,7 @@ namespace iosu
{
std::unique_lock _l(sInternalMutex);
cemu_assert(messageCount != 0);
cemu_assert_debug(messageArray);
auto it = std::find_if(sMsgQueuePool.begin(), sMsgQueuePool.end(), [](const IOSMessageQueue& q) { return q.msgArraySize == 0; });
if (it == sMsgQueuePool.end())
{
@@ -390,12 +393,13 @@ namespace iosu
bool isAllocated{false};
};
SysAllocator<IOSDispatchableCommand, 96> sIPCDispatchableCommandPool;
CafeStaticVar<IOSDispatchableCommand, 96> sIPCDispatchableCommandPool{s_kernelStaticData};
std::queue<IOSDispatchableCommand*> sIPCFreeDispatchableCommands;
FSpinlock sIPCDispatchableCommandPoolLock;
void _IPCInitDispatchablePool()
{
cemu_assert_debug(sIPCDispatchableCommandPool.IsAllocated());
sIPCDispatchableCommandPoolLock.lock();
while (!sIPCFreeDispatchableCommands.empty())
sIPCFreeDispatchableCommands.pop();
@@ -754,6 +758,7 @@ namespace iosu
{
void SystemLaunch() override
{
s_kernelStaticData.Allocate();
_IPCInitDispatchablePool();
// start timer thread
sTimerThreadStop = false;
@@ -768,6 +773,7 @@ namespace iosu
m_timerThread.join();
// reset resources
// todo
s_kernelStaticData.Deallocate();
}
std::thread m_timerThread;
+5 -1
View File
@@ -581,6 +581,8 @@ namespace iosu
namespace acp
{
constinit IOSUStaticData s_staticData;
iosu::nn::IPCService::WorkArea s_ipcServiceWorkArea(s_staticData);
uint64 _ACPGetTimestamp()
{
@@ -780,7 +782,7 @@ namespace iosu
class AcpMainService : public iosu::nn::IPCService
{
public:
AcpMainService() : iosu::nn::IPCService("/dev/acp_main") {}
AcpMainService() : iosu::nn::IPCService("/dev/acp_main", s_ipcServiceWorkArea) {}
nnResult ServiceCall(IPCServiceCall& serviceCall) override
{
@@ -796,12 +798,14 @@ namespace iosu
{
void TitleStart() override
{
s_staticData.Allocate();
gACPMainService.Start();
// gACPMainService.SetTimerUpdate(1000); // call TimerUpdate() once a second
}
void TitleStop() override
{
gACPMainService.Stop();
s_staticData.Deallocate();
}
}sIOSUModuleNNACP;
+6 -1
View File
@@ -384,6 +384,9 @@ namespace iosu
{
namespace act
{
constinit IOSUStaticData s_staticData;
nn::IPCService::WorkArea s_workArea(s_staticData);
uint8 getCurrentAccountSlot()
{
return 1;
@@ -605,7 +608,7 @@ namespace iosu
class ActService : public iosu::nn::IPCService
{
public:
ActService() : iosu::nn::IPCService("/dev/act") {}
ActService() : iosu::nn::IPCService("/dev/act", s_workArea) {}
nnResult ServiceCall(IPCServiceCall& serviceCall) override
{
@@ -619,12 +622,14 @@ namespace iosu
void Initialize()
{
s_staticData.Allocate();
gActService.Start();
}
void Stop()
{
gActService.Stop();
s_staticData.Deallocate();
}
}
}
+6 -1
View File
@@ -20,6 +20,9 @@ namespace iosu
{
namespace fpd
{
constinit IOSUStaticData s_staticData;
nn::IPCSimpleService::WorkArea s_workArea(s_staticData);
using NotificationRunningId = uint64;
struct NotificationEntry
@@ -362,7 +365,7 @@ namespace iosu
std::vector<FPDClient*> m_clients;
public:
FPDService() : iosu::nn::IPCSimpleService("/dev/fpd") {}
FPDService() : iosu::nn::IPCSimpleService("/dev/fpd", s_workArea) {}
std::string GetThreadName() override
{
@@ -1510,6 +1513,7 @@ namespace iosu
{
void TitleStart() override
{
s_staticData.Allocate();
gFPDService.Start();
gFPDService.SetTimerUpdate(1000); // call TimerUpdate() once a second
}
@@ -1517,6 +1521,7 @@ namespace iosu
{
gFPDService.StopFriendSession();
gFPDService.Stop();
s_staticData.Deallocate();
}
}sIOSUModuleNNFPD;
+6 -2
View File
@@ -1,7 +1,6 @@
#include "iosu_ioctl.h"
#include "iosu_mcp.h"
#include "Cafe/OS/libs/nn_common.h"
#include "util/tinyxml2/tinyxml2.h"
#include "config/CemuConfig.h"
#include "Cafe/TitleList/GameInfo.h"
@@ -10,6 +9,7 @@
#include "Cafe/CafeSystem.h"
#include "Cafe/IOSU/iosu_ipc_common.h"
#include "Cafe/IOSU/kernel/iosu_kernel.h"
#include "Common/CafeStaticVar.h"
using namespace iosu::kernel;
@@ -21,6 +21,7 @@ namespace iosu
}iosuMcp = { 0 };
std::recursive_mutex sTitleInfoMutex;
constinit IOSUStaticData s_mcpStaticData;
bool sHasAllTitlesMounted = false;
@@ -159,7 +160,7 @@ namespace iosu
namespace mcp
{
IOSMsgQueueId sMCPIoMsgQueue;
SysAllocator<iosu::kernel::IOSMessage, 352> _m_sMCPIoMsgQueueMsgBuffer;
CafeStaticVar<iosu::kernel::IOSMessage, 352> _m_sMCPIoMsgQueueMsgBuffer{s_mcpStaticData};
std::thread sMCPIoThread;
struct MCPClient
@@ -253,6 +254,7 @@ namespace iosu
void Init()
{
s_mcpStaticData.Allocate();
for (auto& it : sMCPClientArray)
it.ReleaseAndCleanup();
sMCPIoMsgQueue = (IOSMsgQueueId)IOS_CreateMessageQueue(_m_sMCPIoMsgQueueMsgBuffer.GetPtr(), _m_sMCPIoMsgQueueMsgBuffer.GetCount());
@@ -266,6 +268,8 @@ namespace iosu
{
IOS_SendMessage(sMCPIoMsgQueue, 0, 0);
sMCPIoThread.join();
IOS_DestroyMessageQueue(sMCPIoMsgQueue);
s_mcpStaticData.Deallocate();
}
};
}
+10 -8
View File
@@ -1,6 +1,8 @@
#pragma once
#include "Common/CafeString.h"
template<typename T, size_t count, size_t alignment> class RPLStaticVar;
namespace nn::boss
{
typedef uint32 BossResult;
@@ -54,7 +56,7 @@ namespace nn::boss
VTableEntry rtti;
VTableEntry dtor;
};
static inline SysAllocator<VTable> s_titleVTable;
static CafeStaticVar<VTable, 1, 32> s_titleVTable;
static Title* ctor(Title* _this);
static void dtor(Title* _this, uint32 options);
@@ -78,7 +80,7 @@ namespace nn::boss
VTableEntry rtti;
VTableEntry dtor;
};
static inline SysAllocator<VTable> s_VTable;
static CafeStaticVar<VTable, 1, 32> s_VTable;
uint32be accountId;
MEMPTR<void> vTablePtr;
@@ -232,7 +234,7 @@ namespace nn::boss
VTableEntry RegisterPreprocess; // todo - double check the offset
VTableEntry unk1;
};
static inline SysAllocator<VTableTaskSetting> s_VTable;
static CafeStaticVar<VTableTaskSetting, 1, 32> s_VTable;
static TaskSetting* ctor(TaskSetting* _thisptr);
static void dtor(TaskSetting* _this, uint32 options);
@@ -280,7 +282,7 @@ namespace nn::boss
{
struct VTableNetTaskSetting : public VTableTaskSetting
{ };
static inline SysAllocator<VTableNetTaskSetting> s_VTable;
static CafeStaticVar<VTableNetTaskSetting, 1, 32> s_VTable;
static NetTaskSetting* ctor(NetTaskSetting* _thisptr);
static BossResult AddCaCert(NetTaskSetting* _thisptr, const char* name);
@@ -300,7 +302,7 @@ namespace nn::boss
VTableEntry rttiNetTaskSetting; // unknown
};
static_assert(sizeof(VTableNbdlTaskSetting) == 8*5);
static inline SysAllocator<VTableNbdlTaskSetting> s_VTable;
static CafeStaticVar<VTableNbdlTaskSetting, 1, 32> s_VTable;
static NbdlTaskSetting* ctor(NbdlTaskSetting* _thisptr);
static BossResult Initialize(NbdlTaskSetting* _thisptr, const char* bossCode, uint64 directorySizeLimit, const char* bossDirectory);
@@ -323,7 +325,7 @@ namespace nn::boss
VTableEntry rttiNetTaskSetting; // unknown
};
static_assert(sizeof(VTableRawUlTaskSetting) == 8*5);
static inline SysAllocator<VTableRawUlTaskSetting> s_VTable;
static CafeStaticVar<VTableRawUlTaskSetting, 1, 32> s_VTable;
static RawUlTaskSetting* ctor(RawUlTaskSetting* _thisptr);
static void dtor(RawUlTaskSetting* _this, uint32 options);
@@ -339,7 +341,7 @@ namespace nn::boss
VTableEntry rttiNetTaskSetting; // unknown
};
static_assert(sizeof(VTableRawDlTaskSetting) == 8*5);
static inline SysAllocator<VTableRawDlTaskSetting> s_VTable;
static CafeStaticVar<VTableRawDlTaskSetting, 1, 32> s_VTable;
static RawDlTaskSetting* ctor(RawDlTaskSetting* _thisptr);
static BossResult Initialize(RawDlTaskSetting* _thisptr, const char* url, bool newArrival, bool led, const char* fileName, const char* bossDirectory);
@@ -360,7 +362,7 @@ namespace nn::boss
struct VTablePlayReportSetting : public VTableRawUlTaskSetting
{};
static_assert(sizeof(VTablePlayReportSetting) == 8*5);
static inline SysAllocator<VTablePlayReportSetting> s_VTable;
static CafeStaticVar<VTablePlayReportSetting, 1, 32> s_VTable;
static PlayReportSetting* ctor(PlayReportSetting* _this);
static void dtor(PlayReportSetting* _this, uint32 options);
+16 -1
View File
@@ -25,6 +25,9 @@
namespace iosu::boss
{
constinit IOSUStaticData s_staticData;
nn::IPCService::WorkArea s_workArea(s_staticData);
using namespace ::nn::boss;
static constexpr nnResult RESULT_SUCCESS = 0x200080;
@@ -975,7 +978,7 @@ namespace iosu::boss
class BossMainService : public iosu::nn::IPCService
{
public:
BossMainService() : iosu::nn::IPCService("/dev/boss") {}
BossMainService() : iosu::nn::IPCService("/dev/boss", s_workArea) {}
nnResult ServiceCall(IPCServiceCall& serviceCall) override
{
@@ -1412,6 +1415,18 @@ namespace iosu::boss
class : public ::IOSUModule
{
void SystemLaunch() override
{
s_staticData.Allocate();
}
void SystemExit() override
{
s_bossService.Stop();
s_bossDaemon.Stop();
s_staticData.Deallocate();
}
void TitleStart() override
{
s_bossService.Start();
+2 -2
View File
@@ -37,7 +37,7 @@ namespace iosu
{
if(!GetThreadName().empty())
SetThreadName(GetThreadName().c_str());
m_msgQueueId = IOS_CreateMessageQueue(_m_msgBuffer.GetPtr(), _m_msgBuffer.GetCount());
m_msgQueueId = IOS_CreateMessageQueue( m_workArea._m_msgBuffer.GetPtr(), m_workArea._m_msgBuffer.GetCount());
cemu_assert(!IOS_ResultIsError((IOS_ERROR)m_msgQueueId));
IOS_ERROR r = IOS_RegisterResourceManager(m_devicePath.c_str(), m_msgQueueId);
cemu_assert(!IOS_ResultIsError(r));
@@ -158,7 +158,7 @@ namespace iosu
std::string serviceName = m_devicePath.substr(m_devicePath.find_last_of('/') == std::string::npos ? 0 : m_devicePath.find_last_of('/') + 1);
serviceName.insert(0, "NNsvc_");
SetThreadName(serviceName.c_str());
m_msgQueueId = IOS_CreateMessageQueue(_m_msgBuffer.GetPtr(), _m_msgBuffer.GetCount());
m_msgQueueId = IOS_CreateMessageQueue(m_workArea._m_msgBuffer.GetPtr(), m_workArea._m_msgBuffer.GetCount());
cemu_assert(!IOS_ResultIsError((IOS_ERROR)m_msgQueueId));
IOS_ERROR r = IOS_RegisterResourceManager(m_devicePath.c_str(), m_msgQueueId);
cemu_assert(!IOS_ResultIsError(r));
+19 -4
View File
@@ -3,6 +3,7 @@
#include "Cafe/IOSU/iosu_ipc_common.h"
#include "Cafe/IOSU/iosu_types_common.h"
#include "Cafe/OS/libs/nn_common.h"
#include "Common/CafeStaticVar.h"
namespace iosu
{
@@ -12,7 +13,14 @@ namespace iosu
class IPCSimpleService
{
public:
IPCSimpleService(std::string_view devicePath) : m_devicePath(devicePath) {};
struct WorkArea // must be in guest memory. Provided by caller
{
WorkArea(IOSUStaticData& staticData) : _m_msgBuffer(staticData)
{}
CafeStaticVar<iosu::kernel::IOSMessage, 128> _m_msgBuffer;
};
IPCSimpleService(std::string_view devicePath, WorkArea& workArea) : m_devicePath(devicePath), m_workArea(workArea) {};
virtual ~IPCSimpleService() {};
virtual void StartService() {};
@@ -70,7 +78,7 @@ namespace iosu
bool m_delayResponse{false};
IOSMsgQueueId m_msgQueueId;
SysAllocator<iosu::kernel::IOSMessage, 128> _m_msgBuffer;
WorkArea& m_workArea;
};
// a complex service interface which wraps Ioctlv and adds an additional service channel, used by /dev/act, /dev/acp_main, /dev/boss and most nn services
@@ -91,6 +99,13 @@ namespace iosu
uint32be nnResultCode;
};
public:
struct WorkArea // must be in guest memory. Provided by caller
{
WorkArea(IOSUStaticData& staticData) : _m_msgBuffer(staticData)
{}
CafeStaticVar<iosu::kernel::IOSMessage, 128> _m_msgBuffer;
};
class IPCParameterStream // input stream for parameters
{
public:
@@ -308,7 +323,7 @@ namespace iosu
sint8 m_outputBufferIndex{1};
};
IPCService(std::string_view devicePath) : m_devicePath(devicePath) {};
IPCService(std::string_view devicePath, WorkArea& workArea) : m_devicePath(devicePath), m_workArea(workArea) {};
virtual ~IPCService() {};
virtual IOSDevHandle CreateClientHandle()
@@ -340,7 +355,7 @@ namespace iosu
std::atomic_bool m_threadInitialized{ false };
IOSMsgQueueId m_msgQueueId;
SysAllocator<iosu::kernel::IOSMessage, 128> _m_msgBuffer;
WorkArea& m_workArea;
};
};
+1 -1
View File
@@ -287,7 +287,7 @@ bool RPLLoader_ProcessHeaders(std::string_view moduleName, uint8* rplData, uint3
fileName.append(rplLoaderContext->IsRPX() ? ".rpx" : ".rpl");
// allocate modulename in PPC memory
rplLoaderContext->ppcName = coreinit_allocFromSysArea(fileName.size() + 1, 4);
rplLoaderContext->ppcName = OSAllocFromSystem(fileName.size() + 1, 4);
memcpy(rplLoaderContext->ppcName.GetPtr(), fileName.data(), fileName.size() + 1);
// load CRC section
+3 -2
View File
@@ -29,8 +29,9 @@ namespace coreinit
};
}
// utility functions
// utilities
#include "Cafe/OS/common/OSUtil.h"
#include "Common/CafeStaticVar.h"
// va_list
struct ppc_va_list
@@ -113,4 +114,4 @@ static void* _ppc_va_arg(ppc_va_list* vargs, ppc_va_type argType)
vargs->overflow_arg_area += 8;
return r;
}
}
}
+13 -3
View File
@@ -1,12 +1,14 @@
#include "Cafe/OS/common/OSCommon.h"
#include "Cafe/OS/libs/TCL/TCL.h"
#include "HW/Latte/Core/LattePM4.h"
#include "OS/libs/coreinit/coreinit_Time.h"
#include "Common/CafeStaticVar.h"
namespace TCL
{
SysAllocator<coreinit::OSEvent> s_updateRetirementEvent;
constinit COSStaticData s_rplData;
CafeStaticVar<coreinit::OSEvent> s_updateRetirementEvent{s_rplData};
uint64 s_currentRetireMarker = 0;
struct TCLStatePPC // mapped into PPC space
@@ -14,11 +16,13 @@ namespace TCL
uint64be gpuRetireMarker; // written by GPU
};
SysAllocator<TCLStatePPC> s_tclStatePPC;
CafeStaticVar<TCLStatePPC> s_tclStatePPC{s_rplData};
// called from GPU for timestamp EOP event
void TCLGPUNotifyNewRetirementTimestamp()
{
if (!s_updateRetirementEvent.IsAllocated())
return;
// gpuRetireMarker is updated via event eop command
__OSLockScheduler();
coreinit::OSSignalEventAllInternal(s_updateRetirementEvent.GetPtr());
@@ -165,8 +169,14 @@ namespace TCL
return "tcl";
}
void RPLUnmapped() override
{
s_rplData.Deallocate();
}
void RPLMapped() override
{
s_rplData.Allocate();
cafeExportRegister("TCL", TCLSubmitToRing, LogType::Placeholder);
cafeExportRegister("TCL", TCLTimestamp, LogType::Placeholder);
cafeExportRegister("TCL", TCLWaitTimestamp, LogType::Placeholder);
+11 -2
View File
@@ -5,9 +5,11 @@
#include "Cafe/OS/libs/coreinit/coreinit_Alarm.h"
#include "Cafe/OS/libs/coreinit/coreinit_Time.h"
#include "Cafe/HW/Espresso/PPCCallback.h"
#include "Common/CafeStaticVar.h"
namespace camera
{
constinit COSStaticData s_camStaticData;
struct CAMInitInfo_t
{
@@ -58,8 +60,8 @@ namespace camera
std::vector<struct CameraInstance*> g_activeCameraInstances;
std::recursive_mutex g_mutex_camera;
std::atomic_int g_cameraCounter{ 0 };
SysAllocator<coreinit::OSAlarm_t, 1> g_alarm_camera;
SysAllocator<CAMCallbackParam, 1> g_cameraHandlerParam;
CafeStaticVar<coreinit::OSAlarm_t, 1> g_alarm_camera{s_camStaticData};
CafeStaticVar<CAMCallbackParam, 1> g_cameraHandlerParam{s_camStaticData};
CameraInstance* GetCameraInstanceByHandle(sint32 camHandle)
{
@@ -250,8 +252,15 @@ namespace camera
return "camera";
}
void RPLUnmapped() override
{
coreinit::OSCancelAlarm(g_alarm_camera.GetPtr());
s_camStaticData.Deallocate();
}
void RPLMapped() override
{
s_camStaticData.Allocate();
cafeExportRegister("camera", CAMGetMemReq, LogType::Placeholder);
cafeExportRegister("camera", CAMCheckMemSegmentation, LogType::Placeholder);
cafeExportRegister("camera", CAMInit, LogType::Placeholder);
+8
View File
@@ -184,6 +184,8 @@ void coreinitExport_OSGetSharedData(PPCInterpreter_t* hCPU)
namespace coreinit
{
COSStaticData g_coreinitStaticData;
sint32 OSGetCoreId()
{
return PPCInterpreter_getCoreIndex(PPCInterpreter_getCurrentInstance());
@@ -297,6 +299,7 @@ namespace coreinit
void RPLMapped() override
{
g_coreinitStaticData.Allocate();
coreinit::InitializeCore();
coreinit::InitializeSchedulerLock();
coreinit::InitializeSysHeap();
@@ -360,6 +363,11 @@ namespace coreinit
osLib_addFunction("coreinit", "UCReadSysConfig", coreinitExport_UCReadSysConfig);
};
void RPLUnmapped() override
{
g_coreinitStaticData.Deallocate();
}
void rpl_entry(uint32 moduleHandle, coreinit::RplEntryReason reason) override
{
if (reason == coreinit::RplEntryReason::Loaded)
+4 -3
View File
@@ -1,11 +1,10 @@
#pragma once
#include "Cafe/HW/Espresso/Const.h"
#include "Cafe/OS/RPL/COSModule.h"
class COSStaticData;
#define PPC_CORE_COUNT (Espresso::CORE_COUNT)
#include "Cafe/OS/libs/coreinit/coreinit_MessageQueue.h"
// async callback helper
void InitializeAsyncCallback();
@@ -36,9 +35,11 @@ void OSFreeToSystem(MPTR mem);
namespace coreinit
{
extern COSStaticData g_coreinitStaticData;
sint32 OSGetCoreId();
uint32 OSGetCoreCount();
uint32 OSGetStackPointer();
COSModule* GetModule();
};
};
+4 -5
View File
@@ -10,12 +10,11 @@
namespace coreinit
{
SysAllocator<OSEvent> g_alarmEvent;
SysAllocator<OSThread_t> g_alarmThread;
SysAllocator<uint8, 1024 * 128> _g_alarmThreadStack;
SysAllocator<char, 32> _g_alarmThreadName;
CafeStaticVar<OSEvent> g_alarmEvent{coreinit::g_coreinitStaticData};
CafeStaticVar<OSThread_t> g_alarmThread{coreinit::g_coreinitStaticData};
CafeStaticVar<uint8, 1024 * 128> _g_alarmThreadStack{coreinit::g_coreinitStaticData};
CafeStaticVar<char, 32> _g_alarmThreadName{coreinit::g_coreinitStaticData};
class OSHostAlarm
{
@@ -1,5 +1,7 @@
#include "Cafe/OS/libs/coreinit/coreinit.h"
#include "Cafe/OS/libs/coreinit/coreinit_Thread.h"
#include "util/helpers/fspinlock.h"
#include "Common/CafeStaticVar.h"
struct CoreinitAsyncCallback
{
@@ -71,10 +73,10 @@ std::vector<struct CoreinitAsyncCallback*> CoreinitAsyncCallback::s_asyncCallbac
std::vector<struct CoreinitAsyncCallback*> CoreinitAsyncCallback::s_asyncCallbackQueue;
FSpinlock CoreinitAsyncCallback::s_asyncCallbackSpinlock;
SysAllocator<OSThread_t> g_coreinitCallbackThread;
SysAllocator<uint8, 1024*64> _g_coreinitCallbackThreadStack;
SysAllocator<coreinit::OSSemaphore> g_asyncCallbackAsync;
SysAllocator<char, 32> _g_coreinitCBThreadName;
CafeStaticVar<OSThread_t> g_coreinitCallbackThread{coreinit::g_coreinitStaticData};
CafeStaticVar<uint8, 1024*64> _g_coreinitCallbackThreadStack{coreinit::g_coreinitStaticData};
CafeStaticVar<coreinit::OSSemaphore> g_asyncCallbackAsync{coreinit::g_coreinitStaticData};
CafeStaticVar<char, 32> _g_coreinitCBThreadName{coreinit::g_coreinitStaticData};
void _coreinitCallbackThread(PPCInterpreter_t* hCPU)
{
@@ -113,4 +115,4 @@ void InitializeAsyncCallback()
strcpy(_g_coreinitCBThreadName.GetPtr(), "Callback Thread");
coreinit::OSSetThreadName(g_coreinitCallbackThread.GetPtr(), _g_coreinitCBThreadName.GetPtr());
}
}
+26 -26
View File
@@ -44,7 +44,7 @@ bool strcpy_whole(char* dst, size_t dstLength, const char* src)
namespace coreinit
{
SysAllocator<OSMutex> s_fsGlobalMutex;
CafeStaticVar<OSMutex> s_fsGlobalMutex{coreinit::g_coreinitStaticData};
inline void FSLockMutex()
{
@@ -1056,7 +1056,7 @@ namespace coreinit
return FSA_RESULT::OK;
}
SysAllocator<uint8, 128, 64> _tempFSSpace;
CafeStaticVar<uint8, 128, 64> _tempFSSpace{coreinit::g_coreinitStaticData};
sint32 __FSReadFileAsyncEx(FSClient_t* fsClient, FSCmdBlock_t* fsCmdBlock, void* dest, uint32 size, uint32 count, bool usePos, uint32 filePos, uint32 fileHandle, uint32 flag, uint32 errorMask, FSAsyncParams* fsAsyncParams)
{
@@ -2019,9 +2019,9 @@ namespace coreinit
return FSA_RESULT::OK;
}
SysAllocator<coreinit::IPCBufPool_t*> s_fsaIpcPool;
SysAllocator<uint8, 0x37500> s_fsaIpcPoolBuffer;
SysAllocator<uint32be> s_fsaIpcPoolBufferNumItems;
CafeStaticVar<coreinit::IPCBufPool_t*> s_fsaIpcPool{coreinit::g_coreinitStaticData};
CafeStaticVar<uint8, 0x37500> s_fsaIpcPoolBuffer{coreinit::g_coreinitStaticData};
CafeStaticVar<uint32be> s_fsaIpcPoolBufferNumItems{coreinit::g_coreinitStaticData};
std::mutex sFSAIPCBufferLock;
bool s_fsaInitDone = false;
@@ -2508,27 +2508,27 @@ namespace coreinit
return FSAGetInfoByQuery(client, path, FSA_QUERY_TYPE_FREESPACE, outSize);
}
SysAllocator s_fsaStr_OK("FSA_STATUS_OK");
SysAllocator s_fsaStr_NOT_INIT("FSA_STATUS_NOT_INIT");
SysAllocator s_fsaStr_END_OF_DIRECTORY("FSA_STATUS_END_OF_DIRECTORY");
SysAllocator s_fsaStr_END_OF_FILE("FSA_STATUS_END_OF_FILE");
SysAllocator s_fsaStr_MAX_CLIENTS("FSA_STATUS_MAX_CLIENTS");
SysAllocator s_fsaStr_MAX_FILES("FSA_STATUS_MAX_FILES");
SysAllocator s_fsaStr_MAX_DIRS("FSA_STATUS_MAX_DIRS");
SysAllocator s_fsaStr_ALREADY_EXISTS("FSA_STATUS_ALREADY_EXISTS");
SysAllocator s_fsaStr_NOT_FOUND("FSA_STATUS_NOT_FOUND");
SysAllocator s_fsaStr_PERMISSION_ERROR("FSA_STATUS_PERMISSION_ERROR");
SysAllocator s_fsaStr_INVALID_PARAM("FSA_STATUS_INVALID_PARAM");
SysAllocator s_fsaStr_INVALID_PATH("FSA_STATUS_INVALID_PATH");
SysAllocator s_fsaStr_INVALID_BUFFER("FSA_STATUS_INVALID_BUFFER");
SysAllocator s_fsaStr_INVALID_ALIGNMENT("FSA_STATUS_INVALID_ALIGNMENT");
SysAllocator s_fsaStr_INVALID_CLIENT_HANDLE("FSA_STATUS_INVALID_CLIENT_HANDLE");
SysAllocator s_fsaStr_INVALID_FILE_HANDLE("FSA_STATUS_INVALID_FILE_HANDLE");
SysAllocator s_fsaStr_INVALID_DIR_HANDLE("FSA_STATUS_INVALID_DIR_HANDLE");
SysAllocator s_fsaStr_NOT_FILE("FSA_STATUS_NOT_FILE");
SysAllocator s_fsaStr_NOT_DIR("FSA_STATUS_NOT_DIR");
SysAllocator s_fsaStr_OUT_OF_RESOURCES("FSA_STATUS_OUT_OF_RESOURCES");
SysAllocator s_fsaStr_UNKNOWN("FSA_STATUS_???");
CafeStaticVar s_fsaStr_OK(g_coreinitStaticData, "FSA_STATUS_OK");
CafeStaticVar s_fsaStr_NOT_INIT(g_coreinitStaticData, "FSA_STATUS_NOT_INIT");
CafeStaticVar s_fsaStr_END_OF_DIRECTORY(g_coreinitStaticData, "FSA_STATUS_END_OF_DIRECTORY");
CafeStaticVar s_fsaStr_END_OF_FILE(g_coreinitStaticData, "FSA_STATUS_END_OF_FILE");
CafeStaticVar s_fsaStr_MAX_CLIENTS(g_coreinitStaticData, "FSA_STATUS_MAX_CLIENTS");
CafeStaticVar s_fsaStr_MAX_FILES(g_coreinitStaticData, "FSA_STATUS_MAX_FILES");
CafeStaticVar s_fsaStr_MAX_DIRS(g_coreinitStaticData, "FSA_STATUS_MAX_DIRS");
CafeStaticVar s_fsaStr_ALREADY_EXISTS(g_coreinitStaticData, "FSA_STATUS_ALREADY_EXISTS");
CafeStaticVar s_fsaStr_NOT_FOUND(g_coreinitStaticData, "FSA_STATUS_NOT_FOUND");
CafeStaticVar s_fsaStr_PERMISSION_ERROR(g_coreinitStaticData, "FSA_STATUS_PERMISSION_ERROR");
CafeStaticVar s_fsaStr_INVALID_PARAM(g_coreinitStaticData, "FSA_STATUS_INVALID_PARAM");
CafeStaticVar s_fsaStr_INVALID_PATH(g_coreinitStaticData, "FSA_STATUS_INVALID_PATH");
CafeStaticVar s_fsaStr_INVALID_BUFFER(g_coreinitStaticData, "FSA_STATUS_INVALID_BUFFER");
CafeStaticVar s_fsaStr_INVALID_ALIGNMENT(g_coreinitStaticData, "FSA_STATUS_INVALID_ALIGNMENT");
CafeStaticVar s_fsaStr_INVALID_CLIENT_HANDLE(g_coreinitStaticData, "FSA_STATUS_INVALID_CLIENT_HANDLE");
CafeStaticVar s_fsaStr_INVALID_FILE_HANDLE(g_coreinitStaticData, "FSA_STATUS_INVALID_FILE_HANDLE");
CafeStaticVar s_fsaStr_INVALID_DIR_HANDLE(g_coreinitStaticData, "FSA_STATUS_INVALID_DIR_HANDLE");
CafeStaticVar s_fsaStr_NOT_FILE(g_coreinitStaticData, "FSA_STATUS_NOT_FILE");
CafeStaticVar s_fsaStr_NOT_DIR(g_coreinitStaticData, "FSA_STATUS_NOT_DIR");
CafeStaticVar s_fsaStr_OUT_OF_RESOURCES(g_coreinitStaticData, "FSA_STATUS_OUT_OF_RESOURCES");
CafeStaticVar s_fsaStr_UNKNOWN(g_coreinitStaticData, "FSA_STATUS_???");
const char* FSAGetStatusStr(FSA_RESULT status)
{
+2 -2
View File
@@ -25,7 +25,7 @@ namespace coreinit
uint32 ghs_Errno; // exposed as 'errno' data export
};
SysAllocator<GHSAccessibleData> g_ghs_data;
CafeStaticVar<GHSAccessibleData> g_ghs_data{coreinit::g_coreinitStaticData};
struct ghs_flock
{
@@ -38,7 +38,7 @@ namespace coreinit
std::recursive_mutex g_ghsLock;
std::recursive_mutex g_ghsLockFlock;
SysAllocator<coreinit::OSMutex, GHS_FOPEN_MAX> _flockMutexArray;
CafeStaticVar<coreinit::OSMutex, GHS_FOPEN_MAX> _flockMutexArray{coreinit::g_coreinitStaticData};
bool _flockMutexMask[GHS_FOPEN_MAX]; // if set, mutex in _flockMutexArray is reserved
#define IOB_FLAG_IN (0x1)
+7 -7
View File
@@ -102,8 +102,8 @@ namespace coreinit
//static_assert(sizeof(IPCDriverInstance) == 0x1740);
SysAllocator<IPCResourceBuffer, IPC_NUM_RESOURCE_BUFFERS * Espresso::CORE_COUNT, 0x40> s_ipcResourceBuffers;
SysAllocator<IPCDriver, Espresso::CORE_COUNT, 0x40> s_ipcDriver;
CafeStaticVar<IPCResourceBuffer, IPC_NUM_RESOURCE_BUFFERS * Espresso::CORE_COUNT, 0x40> s_ipcResourceBuffers{coreinit::g_coreinitStaticData};
CafeStaticVar<IPCDriver, Espresso::CORE_COUNT, 0x40> s_ipcDriver{coreinit::g_coreinitStaticData};
IPCDriver& IPCDriver_GetByCore(uint32 coreIndex)
{
@@ -176,11 +176,11 @@ namespace coreinit
/* IPC threads */
SysAllocator<OSThread_t, Espresso::CORE_COUNT> gIPCThread;
SysAllocator<uint8, 0x4000 * Espresso::CORE_COUNT> _gIPCThreadStack;
SysAllocator<uint8, 0x18 * Espresso::CORE_COUNT> _gIPCThreadNameStorage;
SysAllocator<OSMessageQueue, Espresso::CORE_COUNT> gIPCThreadMsgQueue;
SysAllocator<OSMessage, Espresso::CORE_COUNT * IPC_NUM_RESOURCE_BUFFERS> _gIPCThreadSemaphoreStorage;
CafeStaticVar<OSThread_t, Espresso::CORE_COUNT> gIPCThread{coreinit::g_coreinitStaticData};
CafeStaticVar<uint8, 0x4000 * Espresso::CORE_COUNT> _gIPCThreadStack{coreinit::g_coreinitStaticData};
CafeStaticVar<uint8, 0x18 * Espresso::CORE_COUNT> _gIPCThreadNameStorage{coreinit::g_coreinitStaticData};
CafeStaticVar<OSMessageQueue, Espresso::CORE_COUNT> gIPCThreadMsgQueue{coreinit::g_coreinitStaticData};
CafeStaticVar<OSMessage, Espresso::CORE_COUNT * IPC_NUM_RESOURCE_BUFFERS> _gIPCThreadSemaphoreStorage{coreinit::g_coreinitStaticData};
// handler thread for asynchronous callbacks for IPC responses
void __IPCDriverThreadFunc(PPCInterpreter_t* hCPU)
+1 -7
View File
@@ -2,10 +2,8 @@
#include "Cafe/HW/Espresso/PPCCallback.h"
#include "Cafe/OS/libs/coreinit/coreinit.h"
#include "Cafe/OS/RPL/rpl.h"
#include "Cafe/OS/libs/padscore/padscore.h"
#include "Cafe/OS/libs/coreinit/coreinit_SysHeap.h"
#include "Cafe/OS/libs/coreinit/coreinit_Alarm.h"
#include "Cafe/OS/libs/vpad/vpad.h"
#include "Cafe/OS/libs/coreinit/coreinit_GHS.h"
#include "Cafe/OS/libs/coreinit/coreinit_DynLoad.h"
#include "Cafe/OS/libs/coreinit/coreinit_MEM.h"
@@ -159,7 +157,7 @@ struct PreinitUserHeapStruct
MEMPTR<coreinit::MEMHeapBase> heapTempMEM2;
};
SysAllocator<PreinitUserHeapStruct> g_preinitUserParam;
CafeStaticVar<PreinitUserHeapStruct> g_preinitUserParam{coreinit::g_coreinitStaticData};
void InitCafeHeaps()
{
@@ -208,10 +206,6 @@ void coreinit_start(PPCInterpreter_t* hCPU)
RPLLoader_CallEntrypoints();
// init vpadbase (todo - simulate entrypoints for HLE modules)
padscore::start();
vpad::start();
// call entry-type callbacks in graphic packs
for (const auto gp : GraphicPack2::GetActiveGraphicPacks())
{
+18 -18
View File
@@ -6,33 +6,33 @@
#include "Cafe/OS/RPL/rpl.h"
#include "Cafe/OS/libs/coreinit/coreinit_MEM_FrmHeap.h"
#include "coreinit_DynLoad.h"
#include "util/ChunkedHeap/ChunkedHeap.h"
// the system area is a block of memory that exists only in the emulator. It is used to simplify dynamic memory allocation for system data
// this partially overlaps with the system heap from coreinit_SysHeap.cpp -> Use SysHeap for everything
MPTR sysAreaAllocatorOffset = 0;
// it's deprecated -> Use SysHeap/CafeStaticVar for everything
static std::unique_ptr<VHeap> s_cosSysHeap;
static std::mutex s_allocatorMtx;
// deprecated
MPTR coreinit_allocFromSysArea(uint32 size, uint32 alignment)
{
std::unique_lock _(s_allocatorMtx);
cemu_assert_debug(mmuRange_CEMU_AREA.isMapped());
// deprecated, use OSAllocFromSystem instead (for everything but SysAllocator which probably should use its own allocator?)
static std::mutex s_allocator_mutex;
s_allocator_mutex.lock();
sysAreaAllocatorOffset = (sysAreaAllocatorOffset+alignment-1);
sysAreaAllocatorOffset -= (sysAreaAllocatorOffset%alignment);
uint32 newMemOffset = mmuRange_CEMU_AREA.getBase() + sysAreaAllocatorOffset;
sysAreaAllocatorOffset += (size+3)&~3;
if( sysAreaAllocatorOffset >= mmuRange_CEMU_AREA.getSize() )
{
if (!s_cosSysHeap)
s_cosSysHeap = std::make_unique<VHeap>(mmuRange_CEMU_AREA.getPtr(), mmuRange_CEMU_AREA.getSize());
MEMPTR<void> r = s_cosSysHeap->alloc(size, alignment);
if (!r)
cemuLog_log(LogType::Force, "Ran out of system memory");
cemu_assert(false); // out of bounds
}
s_allocator_mutex.unlock();
return newMemOffset;
cemu_assert(r);
return r.GetMPTR();
}
void coreinit_freeToSysArea(MPTR mem)
{
// todo
cemu_assert(mem != MPTR_NULL);
std::unique_lock _(s_allocatorMtx);
s_cosSysHeap->free(MEMPTR<void>(mem).GetPtr());
}
namespace coreinit
@@ -50,7 +50,7 @@ namespace coreinit
MEMList g_list3;
std::array<uint32, 3> gHeapFillValues{ 0xC3C3C3C3, 0xF3F3F3F3, 0xD3D3D3D3 };
SysAllocator<OSSpinLock> gHeapGlobalLock;
CafeStaticVar<OSSpinLock> gHeapGlobalLock{coreinit::g_coreinitStaticData};
MEMHeapBase* gDefaultHeap;
bool MEMHeapTable_Add(MEMHeapBase* heap)
@@ -562,7 +562,7 @@ namespace coreinit
hCPU->instructionPointer = gCoreinitData->MEMFreeToDefaultHeap.GetMPTR();
}
SysAllocator<MEMAllocatorFunc> gDefaultHeapAllocator;
CafeStaticVar<MEMAllocatorFunc> gDefaultHeapAllocator{coreinit::g_coreinitStaticData};
void coreinitExport_MEMInitAllocatorForDefaultHeap(PPCInterpreter_t* hCPU)
{
@@ -828,7 +828,7 @@ void _DefaultAllocatorForExpHeap_Free(PPCInterpreter_t* hCPU)
osLib_returnFromFunction(hCPU, 0);
}
SysAllocator<MEMAllocatorFunc> gExpHeapDefaultAllocator;
CafeStaticVar<MEMAllocatorFunc> gExpHeapDefaultAllocator{coreinit::g_coreinitStaticData};
void MEMInitAllocatorForExpHeap(MEMAllocator* allocator, MEMHeapHandle heap, sint32 alignment)
{
@@ -6,8 +6,8 @@ namespace coreinit
void UpdateSystemMessageQueue();
void HandleReceivedSystemMessage(OSMessage* msg);
SysAllocator<OSMessageQueue> g_systemMessageQueue;
SysAllocator<OSMessage, 16> _systemMessageQueueArray;
CafeStaticVar<OSMessageQueue> g_systemMessageQueue{coreinit::g_coreinitStaticData};
CafeStaticVar<OSMessage, 16> _systemMessageQueueArray{coreinit::g_coreinitStaticData};
void OSInitMessageQueueEx(OSMessageQueue* msgQueue, OSMessage* msgArray, uint32 msgCount, void* userData)
{
@@ -174,7 +174,7 @@ namespace coreinit
/************* OSRendezvous ************/
SysAllocator<OSEvent> g_rendezvousEvent;
CafeStaticVar<OSEvent> g_rendezvousEvent{coreinit::g_coreinitStaticData};
void OSInitRendezvous(OSRendezvous* rendezvous)
{
@@ -3,7 +3,7 @@
namespace coreinit
{
SysAllocator<OSSystemInfo> g_system_info;
CafeStaticVar<OSSystemInfo> g_system_info{coreinit::g_coreinitStaticData};
const OSSystemInfo& OSGetSystemInfo()
{
+11 -11
View File
@@ -65,9 +65,9 @@ namespace coreinit
std::vector<std::thread> sSchedulerThreads;
std::mutex sSchedulerStateMtx;
SysAllocator<OSThreadQueue> g_activeThreadQueue; // list of all threads (can include non-detached inactive threads)
CafeStaticVar<OSThreadQueue> g_activeThreadQueue{coreinit::g_coreinitStaticData}; // list of all threads (can include non-detached inactive threads)
SysAllocator<OSThreadQueue, 3> g_coreRunQueue;
CafeStaticVar<OSThreadQueue, 3> g_coreRunQueue{coreinit::g_coreinitStaticData};
CounterSemaphore g_coreRunQueueThreadCount[3];
bool g_isMulticoreMode;
@@ -1485,8 +1485,8 @@ namespace coreinit
return sSchedulerActive;
}
SysAllocator<OSThread_t, PPC_CORE_COUNT> s_defaultThreads;
SysAllocator<uint8, PPC_CORE_COUNT * 1024 * 1024> s_stack;
CafeStaticVar<OSThread_t, PPC_CORE_COUNT> s_defaultThreads{coreinit::g_coreinitStaticData};
CafeStaticVar<uint8, PPC_CORE_COUNT * 1024 * 1024> s_stack{coreinit::g_coreinitStaticData};
OSThread_t* OSGetDefaultThread(sint32 coreIndex)
{
@@ -1532,10 +1532,10 @@ namespace coreinit
MEMPTR<void> deallocatorFunc;
};
SysAllocator<OSThread_t> terminatorThread;
SysAllocator<uint8, 16 * 1024> threadStack;
SysAllocator<char, 64> threadName;
SysAllocator<OSSemaphore> semaphoreQueuedDeallocators;
CafeStaticVar<OSThread_t> terminatorThread{coreinit::g_coreinitStaticData};
CafeStaticVar<uint8, 16 * 1024> threadStack{coreinit::g_coreinitStaticData};
CafeStaticVar<char, 64> threadName{coreinit::g_coreinitStaticData};
CafeStaticVar<OSSemaphore> semaphoreQueuedDeallocators{coreinit::g_coreinitStaticData};
ConcurrentQueue<DeallocatorQueueEntry> queueDeallocators;
};
@@ -1575,18 +1575,18 @@ namespace coreinit
}
}
SysAllocator<char, 64> _defaultThreadName[PPC_CORE_COUNT];
CafeStaticVar<std::array<char, 64>, PPC_CORE_COUNT> _defaultThreadName{coreinit::g_coreinitStaticData};
void __OSInitDefaultThreads()
{
for (sint32 i = 0; i < PPC_CORE_COUNT; i++)
{
sprintf(_defaultThreadName[i].GetPtr(), "Default Core %d", i);
sprintf(_defaultThreadName[i].data(), "Default Core %d", i);
OSThread_t* coreDefaultThread = coreinit::OSGetDefaultThread(i);
uint32 stackSize;
void* stackBase = coreinit::OSGetDefaultThreadStack(i, stackSize);
coreinit::OSCreateThreadType(coreDefaultThread, MPTR_NULL, 0, nullptr, (uint8*)stackBase + stackSize, stackSize, 16, 1 << i, OSThread_t::THREAD_TYPE::TYPE_APP);
coreinit::OSSetThreadName(coreDefaultThread, _defaultThreadName[i].GetPtr());
coreinit::OSSetThreadName(coreDefaultThread, _defaultThreadName[i].data());
}
}
+9 -2
View File
@@ -1,4 +1,4 @@
#include "Cafe/OS/common/OSCommon.h"
#include "Cafe/OS/common/OSCommon.h"
#include "erreula.h"
#include "Cafe/HW/Latte/Renderer/Renderer.h"
#include "util/helpers/helpers.h"
@@ -15,6 +15,7 @@ namespace nn
{
namespace erreula
{
constinit COSStaticData s_erreulaStaticData;
enum class ErrorDialogType : uint32
{
@@ -222,7 +223,7 @@ namespace erreula
struct ErrEula_t
{
SysAllocator<coreinit::OSMutex> mutex;
CafeStaticVar<coreinit::OSMutex> mutex{s_erreulaStaticData};
uint32 regionType{0};
uint32 langType{0};
MEMPTR<coreinit::FSClient_t> fsClient;
@@ -494,8 +495,14 @@ namespace erreula
return "erreula";
}
void RPLUnmapped() override
{
s_erreulaStaticData.Deallocate();
}
void RPLMapped() override
{
s_erreulaStaticData.Allocate();
cafeExportRegisterFunc(ErrEulaCreate, "erreula", "ErrEulaCreate__3RplFPUcQ3_2nn7erreula10RegionTypeQ3_2nn7erreula8LangTypeP8FSClient", LogType::Placeholder);
cafeExportRegisterFunc(ErrEulaDestroy, "erreula", "ErrEulaDestroy__3RplFv", LogType::Placeholder);
+8
View File
@@ -313,6 +313,8 @@ void gx2Export_GX2SetSemaphore(PPCInterpreter_t* hCPU)
namespace GX2
{
constinit COSStaticData s_gx2StaticData;
class : public COSModule
{
public:
@@ -326,8 +328,14 @@ namespace GX2
return "gx2";
}
void RPLUnmapped() override
{
s_gx2StaticData.Deallocate();
}
void RPLMapped() override
{
s_gx2StaticData.Allocate();
osLib_addFunction("gx2", "GX2GetContextStateDisplayList", gx2Export_GX2GetContextStateDisplayList);
// swap, vsync & timing
+3
View File
@@ -12,8 +12,11 @@
// general
class COSStaticData;
namespace GX2
{
extern COSStaticData s_gx2StaticData;
COSModule* GetModule();
}
+3 -1
View File
@@ -60,7 +60,7 @@ namespace GX2
uint64be lastSubmissionTime;
};
SysAllocator<GX2CommandState> s_commandState;
CafeStaticVar<GX2CommandState> s_commandState{s_gx2StaticData};
GX2PerCoreCBState s_mainCoreLastCommandState;
bool s_cbBufferIsInternallyAllocated;
@@ -529,6 +529,8 @@ namespace GX2
void GX2CommandResetToDefaultState()
{
if (!s_commandState.IsAllocated())
return;
s_commandState->commandPoolBase = nullptr;
s_commandState->commandPoolSizeInU32s = 0;
s_commandState->gpuCommandReadPtr = nullptr;
+8 -7
View File
@@ -12,9 +12,8 @@
namespace GX2
{
SysAllocator<coreinit::OSThreadQueue> g_vsyncThreadQueue;
SysAllocator<coreinit::OSThreadQueue> g_flipThreadQueue;
CafeStaticVar<coreinit::OSThreadQueue> g_vsyncThreadQueue{s_gx2StaticData};
CafeStaticVar<coreinit::OSThreadQueue> g_flipThreadQueue{s_gx2StaticData};
void GX2SetGPUFence(uint32be* fencePtr, uint32 mask, uint32 compareOp, uint32 compareValue)
{
@@ -143,9 +142,9 @@ namespace GX2
// event callback thread
bool s_callbackThreadLaunched{};
SysAllocator<OSThread_t> s_eventCallbackThread;
SysAllocator<uint8, 0x2000> s_eventCallbackThreadStack;
SysAllocator<char, 64> s_eventCallbackThreadName;
CafeStaticVar<OSThread_t> s_eventCallbackThread{s_gx2StaticData};
CafeStaticVar<uint8, 0x2000> s_eventCallbackThreadStack{s_gx2StaticData};
CafeStaticVar<char, 64> s_eventCallbackThreadName{s_gx2StaticData};
// event callback queue
struct GX2EventQueueEntry
{
@@ -154,11 +153,13 @@ namespace GX2
GX2CallbackEventType eventType{(GX2CallbackEventType)-1};
};
SysAllocator<coreinit::OSSemaphore> s_eventCbQueueSemaphore;
CafeStaticVar<coreinit::OSSemaphore> s_eventCbQueueSemaphore{s_gx2StaticData};
ConcurrentQueue<GX2EventQueueEntry> s_eventCbQueue;
void __GX2NotifyEvent(GX2CallbackEventType eventType)
{
if (!g_vsyncThreadQueue.IsAllocated())
return;
if ((size_t)eventType >= GX2CallbackEventTypeCount)
{
cemu_assert_debug(false);
+1 -1
View File
@@ -78,7 +78,7 @@ void gx2Export_GX2SampleBottomGPUCycle(PPCInterpreter_t* hCPU)
namespace GX2
{
SysAllocator<uint8, 640 * 480 * 4, 0x1000> _lastFrame;
CafeStaticVar<uint8, 640 * 480 * 4, 0x1000> _lastFrame{s_gx2StaticData};
uint32 sGX2MainCoreIndex = 0;
void _test_AddrLib();
+9 -1
View File
@@ -29,6 +29,8 @@
namespace nfc
{
constinit COSStaticData s_nfcStaticData;
struct NFCContext
{
bool isInitialized;
@@ -56,7 +58,7 @@ namespace nfc
void* writeContext;
MPTR getTagInfoCallback;
SysAllocator<NFCTagInfo> tagInfo;
CafeStaticVar<NFCTagInfo> tagInfo{s_nfcStaticData};
fs::path tagPath;
std::shared_ptr<TagV0> tag;
@@ -646,8 +648,14 @@ namespace nfc
return "nfc";
}
void RPLUnmapped() override
{
s_nfcStaticData.Deallocate();
}
void RPLMapped() override
{
s_nfcStaticData.Allocate();
cafeExportRegister("nfc", NFCInit, LogType::NFC);
cafeExportRegister("nfc", NFCInitEx, LogType::NFC);
cafeExportRegister("nfc", NFCShutdown, LogType::NFC);
+25 -8
View File
@@ -15,19 +15,30 @@ namespace nn
{
namespace boss
{
constinit COSStaticData s_rplData;
CafeStaticVar<Title::VTable> Title::s_titleVTable{s_rplData};
CafeStaticVar<BossAccount::VTable> BossAccount::s_VTable{s_rplData};
CafeStaticVar<TaskSetting::VTableTaskSetting> TaskSetting::s_VTable{s_rplData};
CafeStaticVar<NetTaskSetting::VTableNetTaskSetting> NetTaskSetting::s_VTable{s_rplData};
CafeStaticVar<NbdlTaskSetting::VTableNbdlTaskSetting> NbdlTaskSetting::s_VTable{s_rplData};
CafeStaticVar<RawUlTaskSetting::VTableRawUlTaskSetting> RawUlTaskSetting::s_VTable{s_rplData};
CafeStaticVar<RawDlTaskSetting::VTableRawDlTaskSetting> RawDlTaskSetting::s_VTable{s_rplData};
CafeStaticVar<PlayReportSetting::VTablePlayReportSetting> PlayReportSetting::s_VTable{s_rplData};
IPCServiceClient s_ipcClient;
static constexpr BossResult resultSuccess = BUILD_NN_RESULT(NN_RESULT_LEVEL_SUCCESS, NN_RESULT_MODULE_NN_BOSS, 0x80);
static constexpr BossResult resultInvalidParam = BUILD_NN_RESULT(NN_RESULT_LEVEL_LVL6, NN_RESULT_MODULE_NN_BOSS, 0x3780);
static constexpr BossResult resultUknA0220300 = BUILD_NN_RESULT(NN_RESULT_LEVEL_STATUS, NN_RESULT_MODULE_NN_BOSS, 0x20300);
SysAllocator<coreinit::OSMutex> g_mutex;
CafeStaticVar<coreinit::OSMutex> g_mutex{s_rplData};
sint32 g_initCounter = 0;
bool g_isInitialized = false;
#define DTOR_WRAPPER(__TYPE) RPLLoader_MakePPCCallable([](PPCInterpreter_t* hCPU) { dtor(MEMPTR<__TYPE>(hCPU->gpr[3]), hCPU->gpr[4]); osLib_returnFromFunction(hCPU, 0); })
SysAllocator<uint8, 0x10000, 64> s_ipcBuffer;
CafeStaticVar<uint8, 0x10000, 64> s_ipcBuffer{s_rplData};
constexpr uint32 BOSS_MEM_MAGIC = 0xCAFE4321;
@@ -492,7 +503,7 @@ namespace boss
VTableEntry rtti;
VTableEntry dtor;
};
static inline SysAllocator<VTableTask> s_vTable;
static inline CafeStaticVar<VTableTask> s_vTable{s_rplData};
uint32be persistentId; // 0x00
uint32be uk2; // 0x04
@@ -744,7 +755,7 @@ namespace boss
VTableEntry rttiTask;
};
static_assert(sizeof(VTablePrivilegedTask) == 8*3);
static inline SysAllocator<VTablePrivilegedTask> s_VTable;
static inline CafeStaticVar<VTablePrivilegedTask> s_VTable{s_rplData};
static PrivilegedTask* ctor(PrivilegedTask* _thisptr)
{
@@ -778,7 +789,7 @@ namespace boss
struct VTableAlmightyTask : public VTablePrivilegedTask
{};
static_assert(sizeof(VTableAlmightyTask) == 8*3);
static inline SysAllocator<VTableAlmightyTask> s_VTable;
static inline CafeStaticVar<VTableAlmightyTask> s_VTable{s_rplData};
static AlmightyTask* ctor(AlmightyTask* _thisptr)
{
@@ -850,7 +861,7 @@ namespace boss
VTableEntry rtti;
VTableEntry dtor;
};
static inline SysAllocator<VTableStorage> s_vTable;
static inline CafeStaticVar<VTableStorage> s_vTable{s_rplData};
enum StorageKind
{
@@ -958,7 +969,7 @@ namespace boss
VTableEntry rttiStorage;
};
static_assert(sizeof(VTableAlmightyStorage) == 8*3);
static inline SysAllocator<VTableAlmightyStorage> s_VTable;
static inline CafeStaticVar<VTableAlmightyStorage> s_VTable{s_rplData};
static AlmightyStorage* ctor(AlmightyStorage* _thisptr)
{
@@ -1001,7 +1012,7 @@ namespace boss
VTableEntry rtti;
VTableEntry dtor;
};
static inline SysAllocator<VTableNsData> s_vTable;
static inline CafeStaticVar<VTableNsData> s_vTable{s_rplData};
/* +0x00 */ DataName name;
/* +0x20 */ Storage storage;
@@ -1202,8 +1213,14 @@ namespace nn::boss
return "nn_boss";
}
void RPLUnmapped() override
{
s_rplData.Deallocate();
}
void RPLMapped() override
{
s_rplData.Allocate();
cafeExportRegisterFunc(nn::boss::GetBossState, "nn_boss", "GetBossState__Q2_2nn4bossFv", LogType::NN_BOSS);
// boss lib
+14 -4
View File
@@ -13,6 +13,8 @@ namespace nn
{
namespace fp
{
constinit constinit COSStaticData s_nnfpStaticData;
static const auto FPResult_OkZero = 0;
static const auto FPResult_Ok = BUILD_NN_RESULT(NN_RESULT_LEVEL_SUCCESS, NN_RESULT_MODULE_NN_FP, 0);
static const auto FPResult_InvalidIPCParam = BUILD_NN_RESULT(NN_RESULT_LEVEL_LVL6, NN_RESULT_MODULE_NN_FP, 0x680);
@@ -24,12 +26,12 @@ namespace nn
bool isAdminMode;
bool isLoggedIn;
IOSDevHandle fpdHandle;
SysAllocator<coreinit::OSMutex> fpMutex;
SysAllocator<uint8, 0x12000> g_fpdAllocatorSpace;
CafeStaticVar<coreinit::OSMutex> fpMutex{s_nnfpStaticData};
CafeStaticVar<uint8, 0x12000> g_fpdAllocatorSpace{s_nnfpStaticData};
VHeap* fpBufferHeap{nullptr};
// PPC buffers for async notification query
SysAllocator<uint32be> notificationCount;
SysAllocator<iosu::fpd::FPDNotification, 256> notificationBuffer;
CafeStaticVar<uint32be> notificationCount{s_nnfpStaticData};
CafeStaticVar<iosu::fpd::FPDNotification, 256> notificationBuffer{s_nnfpStaticData};
bool getNotificationCalled{false};
// notification handler
MEMPTR<void> notificationHandler{nullptr};
@@ -49,6 +51,7 @@ namespace nn
{
std::unique_lock _l(m_mtx);
delete g_fp.fpBufferHeap;
g_fp.fpBufferHeap = nullptr;
}
void* Allocate(uint32 size, uint32 alignment)
@@ -766,8 +769,15 @@ namespace nn
return "nn_fp";
}
void RPLUnmapped() override
{
FPIpcBufferAllocator.Destroy();
s_nnfpStaticData.Deallocate();
}
void RPLMapped() override
{
s_nnfpStaticData.Allocate();
g_fp.initCounter = 0;
g_fp.isAdminMode = false;
g_fp.isLoggedIn = false;
+12 -3
View File
@@ -11,13 +11,16 @@
#include "Cafe/OS/libs/coreinit/coreinit_Time.h"
#include "Cafe/OS/libs/coreinit/coreinit_Misc.h"
namespace nn
{
namespace olv
{
static SysAllocator<OSThread_t> s_OlvReleaseBgThread;
SysAllocator<uint8, 1024> s_OlvReleaseBgThreadStack;
SysAllocator<char, 32> s_OlvReleaseBgThreadName;
constinit COSStaticData s_nnolvStaticData;
CafeStaticVar<OSThread_t> s_OlvReleaseBgThread{s_nnolvStaticData};
CafeStaticVar<uint8, 1024> s_OlvReleaseBgThreadStack{s_nnolvStaticData};
CafeStaticVar<char, 32> s_OlvReleaseBgThreadName{s_nnolvStaticData};
void StubPostAppReleaseBackground(PPCInterpreter_t* hCPU)
{
@@ -103,8 +106,14 @@ namespace nn
return "nn_olv";
}
void RPLUnmapped() override
{
s_nnolvStaticData.Deallocate();
}
void RPLMapped() override
{
s_nnolvStaticData.Allocate();
loadOliveInitializeTypes();
loadOliveUploadCommunityTypes();
loadOliveDownloadCommunityTypes();
+11 -4
View File
@@ -4,14 +4,13 @@
#include "Cafe/OS/libs/nn_acp/nn_acp.h"
#include "Cafe/OS/libs/nn_act/nn_act.h"
#include <filesystem>
#include <sstream>
#include "config/ActiveSettings.h"
#include "Cafe/OS/libs/coreinit/coreinit_Thread.h"
#include "Cafe/OS/libs/coreinit/coreinit_FS.h"
#include "Cafe/CafeSystem.h"
#include "Cafe/Filesystem/fsc.h"
#define SAVE_STATUS_OK ((FSStatus)FS_RESULT::SUCCESS)
#define SAVE_MAX_PATH_SIZE (FSA_CMD_PATH_MAX_LENGTH)
@@ -27,6 +26,8 @@ namespace nn
{
namespace save
{
constinit COSStaticData s_rplData;
typedef FSStatus SAVEStatus;
typedef struct
@@ -38,7 +39,7 @@ namespace save
uint32 persistentIdCache[0xC];
}nn_save_t;
SysAllocator<nn_save_t> g_nn_save;
CafeStaticVar<nn_save_t> g_nn_save{s_rplData};
uint32 GetPersistentIdFromLocalCache(uint8 accountSlot)
{
@@ -767,7 +768,7 @@ namespace save
void ResetToDefaultState()
{
if(g_nn_save->initialized)
if(g_nn_save.IsAllocated() && g_nn_save->initialized)
{
SAVEUnmountSaveDir();
g_nn_save->initialized = false;
@@ -782,8 +783,14 @@ namespace save
return "nn_save";
}
void RPLUnmapped() override
{
s_rplData.Deallocate();
}
void RPLMapped() override
{
s_rplData.Allocate();
cafeExportRegister("nn_save", SAVEInit, LogType::Save);
cafeExportRegister("nn_save", SAVEInitSaveDir, LogType::Save);
+11 -2
View File
@@ -4,11 +4,14 @@
#include "config/ActiveSettings.h"
#include "Cafe/CafeSystem.h"
namespace nn
{
typedef uint32 Result;
namespace sl
{
constinit COSStaticData s_nnslStaticData;
struct VTableEntry
{
uint16be offsetA{0};
@@ -66,7 +69,7 @@ namespace nn
VTableEntry dtor;
VTableEntry get;
};
static inline SysAllocator<VTable> s_titleVTable;
static inline CafeStaticVar<VTable> s_titleVTable{s_nnslStaticData};
static WhiteListAccessor* ctor(WhiteListAccessor* _this)
{
@@ -97,7 +100,7 @@ namespace nn
};
static_assert(sizeof(WhiteListAccessor) == 0x04);
SysAllocator<WhiteListAccessor> s_defaultWhiteListAccessor;
CafeStaticVar<WhiteListAccessor> s_defaultWhiteListAccessor{s_nnslStaticData};
WhiteListAccessor* GetDefaultWhiteListAccessor()
{
@@ -112,8 +115,14 @@ namespace nn
return "nn_sl";
}
void RPLUnmapped() override
{
s_nnslStaticData.Deallocate();
}
void RPLMapped() override
{
s_nnslStaticData.Allocate();
cafeExportRegisterFunc(nn::sl::GetDefaultWhiteListAccessor, "nn_sl", "GetDefaultWhiteListAccessor__Q2_2nn2slFv", LogType::NN_SL);
};
+26 -4
View File
@@ -1,17 +1,16 @@
#include "Cafe/OS/common/OSCommon.h"
#include "Cafe/HW/Espresso/PPCCallback.h"
#include <bitset>
#include <mutex>
#include "nsyshid.h"
#include "Cafe/OS/libs/coreinit/coreinit_Thread.h"
#include "Backend.h"
#include "Whitelist.h"
namespace nsyshid
{
constinit COSStaticData s_nsyshidStaticData;
std::list<std::shared_ptr<Backend>> backendList;
std::list<std::shared_ptr<Device>> deviceList;
typedef struct _HIDClient_t
@@ -75,7 +74,7 @@ namespace nsyshid
const int HID_MAX_NUM_DEVICES = 128;
SysAllocator<HID_t, HID_MAX_NUM_DEVICES> HIDPool;
CafeStaticVar<HID_t, HID_MAX_NUM_DEVICES> HIDPool{s_nsyshidStaticData};
std::queue<size_t> HIDPoolIndexQueue;
void InitHIDPoolIndexQueue()
@@ -96,6 +95,9 @@ namespace nsyshid
HID_t* GetFreeHID()
{
std::lock_guard<std::recursive_mutex> lock(hidMutex);
cemu_assert_debug(HIDPool.IsAllocated());
if (!HIDPool.IsAllocated())
return nullptr;
InitHIDPoolIndexQueue();
if (HIDPoolIndexQueue.empty())
{
@@ -952,8 +954,28 @@ namespace nsyshid
return "nsyshid";
}
void RPLUnmapped() override
{
// Stop backends and drop callbacks before their guest descriptors go away.
{
std::lock_guard<std::recursive_mutex> lock(hidMutex);
HIDClientList.clear();
}
DetachAllBackends();
std::list<std::shared_ptr<Device>> remainingDevices;
{
std::lock_guard<std::recursive_mutex> lock(hidMutex);
remainingDevices = deviceList;
}
for (const auto& device : remainingDevices)
DetachDevice(device);
std::lock_guard<std::recursive_mutex> lock(hidMutex);
s_nsyshidStaticData.Deallocate();
}
void RPLMapped() override
{
s_nsyshidStaticData.Allocate();
osLib_addFunction("nsyshid", "HIDAddClient", export_HIDAddClient);
osLib_addFunction("nsyshid", "HIDDelClient", export_HIDDelClient);
osLib_addFunction("nsyshid", "HIDGetDescriptor", export_HIDGetDescriptor);
+11 -4
View File
@@ -79,6 +79,7 @@
#define WU_SO_ESHUTDOWN 0x000F
constinit COSStaticData s_nsysnetData;
typedef signed int WUSOCKET;
@@ -1385,10 +1386,10 @@ void nsysnetExport_gethostbyname(PPCInterpreter_t* hCPU)
return;
}
SysAllocator<wu_hostent> _staticHostent;
SysAllocator<char, 256> _staticHostentName;
SysAllocator<MPTR, 32> _staticHostentPtrList;
SysAllocator<wu_in_addr, 32> _staticHostentEntries;
CafeStaticVar<wu_hostent> _staticHostent{s_nsysnetData};
CafeStaticVar<char, 256> _staticHostentName{s_nsysnetData};
CafeStaticVar<MPTR, 32> _staticHostentPtrList{s_nsysnetData};
CafeStaticVar<wu_in_addr, 32> _staticHostentEntries{s_nsysnetData};
void nsysnetExport_gethostbyaddr(PPCInterpreter_t* hCPU)
{
@@ -2211,8 +2212,14 @@ namespace nsysnet
return "nsysnet";
}
void RPLUnmapped() override
{
s_nsysnetData.Deallocate();
}
void RPLMapped() override
{
s_nsysnetData.Allocate();
cafeExportRegister("nsysnet", inet_ntop, LogType::Socket);
// the below code is the old way of registering API which is deprecated
+16 -1
View File
@@ -7,6 +7,8 @@
#include "WindowSystem.h"
#include "input/InputManager.h"
constinit COSStaticData s_padscoreStaticData;
// KPAD
enum class KPAD_ERROR : sint32
@@ -55,7 +57,7 @@ namespace padscore
WPADState_t g_wpad_state = kWPADStateMaster;
struct {
SysAllocator<coreinit::OSAlarm_t> alarm;
CafeStaticVar<coreinit::OSAlarm_t> alarm{s_padscoreStaticData};
bool kpad_initialized = false;
struct WPADData
@@ -774,8 +776,21 @@ namespace padscore
return "padscore";
}
void RPLUnmapped() override
{
coreinit::OSCancelAlarm(g_padscore.alarm.GetPtr());
s_padscoreStaticData.Deallocate();
}
void rpl_entry(uint32 moduleHandle, coreinit::RplEntryReason reason) override
{
if (reason == coreinit::RplEntryReason::Loaded)
start();
}
void RPLMapped() override
{
s_padscoreStaticData.Allocate();
cafeExportRegister("padscore", WPADIsMplsAttached, LogType::InputAPI);
cafeExportRegister("padscore", WPADGetAccGravityUnit, LogType::InputAPI);
+23 -15
View File
@@ -20,6 +20,8 @@ using namespace coreinit;
namespace proc_ui
{
constinit COSStaticData s_procuiStaticData;
enum class ProcUICoreThreadCommand
{
AcquireForeground = 0x0,
@@ -58,26 +60,26 @@ namespace proc_ui
MEMPTR<void> s_saveCallbackEx; // with custom param and return value, set by ProcUIInitEx()
MEMPTR<void> s_saveCallbackExUserParam;
MEMPTR<coreinit::OSMessageQueue> s_systemMessageQueuePtr;
SysAllocator<coreinit::OSEvent> s_eventStateMessageReceived;
SysAllocator<coreinit::OSEvent> s_eventWaitingBeforeReleaseForeground;
SysAllocator<coreinit::OSEvent> s_eventBackgroundThreadGotMessage;
CafeStaticVar<coreinit::OSEvent> s_eventStateMessageReceived{s_procuiStaticData};
CafeStaticVar<coreinit::OSEvent> s_eventWaitingBeforeReleaseForeground{s_procuiStaticData};
CafeStaticVar<coreinit::OSEvent> s_eventBackgroundThreadGotMessage{s_procuiStaticData};
// procUI core threads
uint32 s_coreThreadStackSize;
bool s_coreThreadsCreated;
std::atomic<ProcUICoreThreadCommand> s_commandForCoreThread;
SysAllocator<OSThread_t> s_coreThreadArray[Espresso::CORE_COUNT];
CafeStaticVar<OSThread_t, Espresso::CORE_COUNT> s_coreThreadArray{s_procuiStaticData};
MEMPTR<void> s_coreThreadStackPerCore[Espresso::CORE_COUNT];
SysAllocator<CafeString<22>> s_coreThread0NameBuffer;
SysAllocator<CafeString<22>> s_coreThread1NameBuffer;
SysAllocator<CafeString<22>> s_coreThread2NameBuffer;
SysAllocator<coreinit::OSEvent> s_eventCoreThreadsNewCommandReady;
SysAllocator<coreinit::OSEvent> s_eventCoreThreadsCommandDone;
SysAllocator<coreinit::OSRendezvous> s_coreThreadRendezvousA;
SysAllocator<coreinit::OSRendezvous> s_coreThreadRendezvousB;
SysAllocator<coreinit::OSRendezvous> s_coreThreadRendezvousC;
CafeStaticVar<CafeString<22>> s_coreThread0NameBuffer{s_procuiStaticData};
CafeStaticVar<CafeString<22>> s_coreThread1NameBuffer{s_procuiStaticData};
CafeStaticVar<CafeString<22>> s_coreThread2NameBuffer{s_procuiStaticData};
CafeStaticVar<coreinit::OSEvent> s_eventCoreThreadsNewCommandReady{s_procuiStaticData};
CafeStaticVar<coreinit::OSEvent> s_eventCoreThreadsCommandDone{s_procuiStaticData};
CafeStaticVar<coreinit::OSRendezvous> s_coreThreadRendezvousA{s_procuiStaticData};
CafeStaticVar<coreinit::OSRendezvous> s_coreThreadRendezvousB{s_procuiStaticData};
CafeStaticVar<coreinit::OSRendezvous> s_coreThreadRendezvousC{s_procuiStaticData};
// background thread
MEMPTR<void> s_backgroundThreadStack;
SysAllocator<OSThread_t> s_backgroundThread;
CafeStaticVar<OSThread_t> s_backgroundThread{s_procuiStaticData};
// user defined heap
MEMPTR<void> s_memoryPoolHeapPtr;
MEMPTR<void> s_memAllocPtr;
@@ -102,8 +104,8 @@ namespace proc_ui
uint32be s_driverArgUkn1;
uint32be s_driverArgUkn2;
bool s_driverInBackground;
SysAllocator<OSDriverInterface> s_ProcUIDriver;
SysAllocator<CafeString<16>> s_ProcUIDriverName;
CafeStaticVar<OSDriverInterface> s_ProcUIDriver{s_procuiStaticData};
CafeStaticVar<CafeString<16>> s_ProcUIDriverName{s_procuiStaticData};
void* _AllocMem(uint32 size)
@@ -854,8 +856,14 @@ namespace proc_ui
return "proc_ui";
}
void RPLUnmapped() override
{
s_procuiStaticData.Deallocate();
}
void RPLMapped() override
{
s_procuiStaticData.Allocate();
reset();
cafeExportRegister("proc_ui", ProcUIInit, LogType::ProcUi);
+5 -4
View File
@@ -1,6 +1,7 @@
#include "Cafe/OS/libs/snd_core/ax.h"
#include "Cafe/OS/libs/snd_core/ax_internal.h"
#include "Cafe/HW/Espresso/PPCState.h"
#include "Common/CafeStaticVar.h"
namespace snd_core
{
@@ -56,8 +57,8 @@ namespace snd_core
}
};
SysAllocator<AUXTVBuffer> __AXAuxTVBuffer;
SysAllocator<AUXDRCBuffer, 2> __AXAuxDRCBuffer;
CafeStaticVar<AUXTVBuffer> __AXAuxTVBuffer{g_sndStaticData};
CafeStaticVar<AUXDRCBuffer, 2> __AXAuxDRCBuffer{g_sndStaticData};
uint32 __AXCurrentAuxInputFrameIndex = 0;
@@ -188,8 +189,8 @@ namespace snd_core
return 0;
}
SysAllocator<MEMPTR<sint32be>, 6> __AXAuxCB_dataPtrs;
SysAllocator<AXAUXCBCHANNELINFO> __AXAuxCB_auxCBStruct;
CafeStaticVar<MEMPTR<sint32be>, 6> __AXAuxCB_dataPtrs{g_sndStaticData};
CafeStaticVar<AXAUXCBCHANNELINFO> __AXAuxCB_auxCBStruct{g_sndStaticData};
void AXAux_Process()
{
+29 -1
View File
@@ -7,13 +7,19 @@
namespace snd_core
{
// snd_core and sndcore2 share the AX implementation in Cemu, but technically they are exclusive/conflicting implementations and no game should use them at the same time
// but just in case we keep g_sndStaticData alive until both modules are unloaded
COSStaticData g_sndStaticData;
static uint32 s_mappedSoundModules = 0;
sndGeneric_t sndGeneric;
void AXResetToDefaultState()
{
sndGeneric = {};
resetNumProcessedFrames();
AXVBP_Reset();
if (g_sndStaticData.IsAllocated())
AXVBP_Reset();
}
bool AXIsInit()
@@ -473,8 +479,19 @@ namespace snd_core
return "snd_core";
}
void RPLUnmapped() override
{
cemu_assert(s_mappedSoundModules > 0);
--s_mappedSoundModules;
if (s_mappedSoundModules == 0)
g_sndStaticData.Deallocate();
}
void RPLMapped() override
{
if (s_mappedSoundModules == 0)
g_sndStaticData.Allocate();
++s_mappedSoundModules;
AXResetToDefaultState();
cafeExportRegisterFunc(sndcore1_AXInit, "snd_core", "AXInit", LogType::SoundAPI);
cafeExportRegisterFunc(sndcore1_AXInitEx, "snd_core", "AXInitEx", LogType::SoundAPI);
@@ -548,8 +565,19 @@ namespace snd_core
return "sndcore2";
}
void RPLUnmapped() override
{
cemu_assert(s_mappedSoundModules > 0);
--s_mappedSoundModules;
if (s_mappedSoundModules == 0)
g_sndStaticData.Deallocate();
}
void RPLMapped() override
{
if (s_mappedSoundModules == 0)
g_sndStaticData.Allocate();
++s_mappedSoundModules;
cafeExportRegisterFunc(sndcore2_AXInitWithParams, "sndcore2", "AXInitWithParams", LogType::SoundAPI);
cafeExportRegisterFunc(sndcore2_AXInit, "sndcore2", "AXInit", LogType::SoundAPI);
cafeExportRegisterFunc(sndcore2_AXInitEx, "sndcore2", "AXInitEx", LogType::SoundAPI);
+6 -2
View File
@@ -1,8 +1,12 @@
#pragma once
#include "Cafe/OS/libs/snd_core/ax.h"
class COSStaticData;
template<typename T, size_t count, size_t alignment> class CafeStaticVar;
namespace snd_core
{
extern COSStaticData g_sndStaticData;
struct sndGeneric_t
{
bool isInitialized{false};
@@ -218,7 +222,7 @@ namespace snd_core
void AXAux_incrementBufferIndex();
// internal mix buffers
extern SysAllocator<sint32, AX_SAMPLES_MAX * AX_TV_CHANNEL_COUNT> __AXTVOutputBuffer;
extern SysAllocator<sint32, AX_SAMPLES_MAX * AX_DRC_CHANNEL_COUNT * 2> __AXDRCOutputBuffer;
extern CafeStaticVar<sint32, AX_SAMPLES_MAX * AX_TV_CHANNEL_COUNT, 32> __AXTVOutputBuffer;
extern CafeStaticVar<sint32, AX_SAMPLES_MAX * AX_DRC_CHANNEL_COUNT * 2, 32> __AXDRCOutputBuffer;
}
+20 -20
View File
@@ -4,6 +4,7 @@
#include "Cafe/HW/Espresso/PPCCallback.h"
#include "Cafe/OS/libs/coreinit/coreinit_Thread.h"
#include "Cafe/OS/libs/coreinit/coreinit_MessageQueue.h"
#include "Common/CafeStaticVar.h"
namespace snd_core
{
@@ -76,12 +77,12 @@ namespace snd_core
static_assert(offsetof(AXFINALMIXCBPARAM, numDevices) == 0x08);
static_assert(offsetof(AXFINALMIXCBPARAM, numChannelOutput) == 0x0A);
SysAllocator<AXFINALMIXCBPARAM> __AXFinalMixCBStructTV;
SysAllocator<AXFINALMIXCBPARAM> __AXFinalMixCBStructDRC;
SysAllocator<AXFINALMIXCBPARAM> __AXFinalMixCBStructRMT;
CafeStaticVar<AXFINALMIXCBPARAM> __AXFinalMixCBStructTV{g_sndStaticData};
CafeStaticVar<AXFINALMIXCBPARAM> __AXFinalMixCBStructDRC{g_sndStaticData};
CafeStaticVar<AXFINALMIXCBPARAM> __AXFinalMixCBStructRMT{g_sndStaticData};
SysAllocator<MEMPTR<sint32>, 6> __AXFinalMixCBStructTV_dataPtrArray;
SysAllocator<MEMPTR<sint32>, 4 * 2> __AXFinalMixCBStructDRC_dataPtrArray;
CafeStaticVar<MEMPTR<sint32>, 6> __AXFinalMixCBStructTV_dataPtrArray{g_sndStaticData};
CafeStaticVar<MEMPTR<sint32>, 4 * 2> __AXFinalMixCBStructDRC_dataPtrArray{g_sndStaticData};
sint32 __AXFinalMixOutputChannelCount[AX_DEV_COUNT] = { 0 }; // number of output channels returned by final mix callback
@@ -89,7 +90,7 @@ namespace snd_core
MPTR __AXFrameCallback = MPTR_NULL; // set via AXRegisterFrameCallback()
MPTR __AXAppFrameCallback[AX_APP_FRAME_CALLBACK_MAX];
MPTR __AXDeviceFinalMixCallback[AX_DEV_COUNT];
SysAllocator<coreinit::OSMutex, 1> __AXAppFrameCallbackMutex;
CafeStaticVar<coreinit::OSMutex, 1> __AXAppFrameCallbackMutex{g_sndStaticData};
void AXResetCallbacks()
{
@@ -211,8 +212,7 @@ namespace snd_core
return 0;
}
SysAllocator<AXRemixMatrices_t, 12> g_remix_matrices;
CafeStaticVar<AXRemixMatrices_t, 12> g_remix_matrices{g_sndStaticData};
sint32 AXSetDeviceRemixMatrix(sint32 deviceId, uint32 inputChannelCount, uint32 outputChannelCount, const MEMPTR<float32be>& matrix)
{
@@ -307,15 +307,15 @@ namespace snd_core
return -10;
}
SysAllocator<sint32, AX_SAMPLES_MAX * AX_TV_CHANNEL_COUNT> __AXTVOutputBuffer;
SysAllocator<sint32, AX_SAMPLES_MAX * AX_DRC_CHANNEL_COUNT * 2> __AXDRCOutputBuffer;
CafeStaticVar<sint32, AX_SAMPLES_MAX * AX_TV_CHANNEL_COUNT> __AXTVOutputBuffer{g_sndStaticData};
CafeStaticVar<sint32, AX_SAMPLES_MAX * AX_DRC_CHANNEL_COUNT * 2> __AXDRCOutputBuffer{g_sndStaticData};
SysAllocator<sint32, AX_SAMPLES_MAX * AX_TV_CHANNEL_COUNT> __AXTempFinalMixTVBuffer;
SysAllocator<sint32, AX_SAMPLES_MAX * AX_DRC_CHANNEL_COUNT * 2> __AXTempFinalMixDRCBuffer;
CafeStaticVar<sint32, AX_SAMPLES_MAX * AX_TV_CHANNEL_COUNT> __AXTempFinalMixTVBuffer{g_sndStaticData};
CafeStaticVar<sint32, AX_SAMPLES_MAX * AX_DRC_CHANNEL_COUNT * 2> __AXTempFinalMixDRCBuffer{g_sndStaticData};
// 48KHz buffers
SysAllocator<sint32, AX_SAMPLES_MAX * AX_TV_CHANNEL_COUNT> __AXTVBuffer48;
SysAllocator<sint32, AX_SAMPLES_MAX * AX_DRC_CHANNEL_COUNT * 2> __AXDRCBuffer48;
CafeStaticVar<sint32, AX_SAMPLES_MAX * AX_TV_CHANNEL_COUNT> __AXTVBuffer48{g_sndStaticData};
CafeStaticVar<sint32, AX_SAMPLES_MAX * AX_DRC_CHANNEL_COUNT * 2> __AXDRCBuffer48{g_sndStaticData};
sint32 AXUpsampleLinear32To48(sint32* inputBuffer, sint32* outputBuffer, sint32* sampleHistory, sint32 sampleCount, bool shiftSamples, sint32 channelCount)
{
@@ -937,7 +937,7 @@ namespace snd_core
void AXIst_HandleDeviceRemix()
{
extern SysAllocator<AXRemixMatrices_t, 12> g_remix_matrices;
extern CafeStaticVar<AXRemixMatrices_t, 12> g_remix_matrices;
extern sint32 __AXOutTVOutputChannelCount;
extern sint32 __AXOutDRCOutputChannelCount;
@@ -966,11 +966,11 @@ namespace snd_core
std::atomic_bool __AXIstIsProcessingFrame = false;
SysAllocator<OSThread_t> __AXIstThread;
SysAllocator<uint8, 0x4000> __AXIstThreadStack;
CafeStaticVar<OSThread_t> __AXIstThread{g_sndStaticData};
CafeStaticVar<uint8, 0x4000> __AXIstThreadStack{g_sndStaticData};
SysAllocator<coreinit::OSMessage, 0x10> __AXIstThreadMsgArray;
SysAllocator<coreinit::OSMessageQueue, 1> __AXIstThreadMsgQueue;
CafeStaticVar<coreinit::OSMessage, 0x10> __AXIstThreadMsgArray{g_sndStaticData};
CafeStaticVar<coreinit::OSMessageQueue, 1> __AXIstThreadMsgQueue{g_sndStaticData};
void AXIst_InitThread()
{
@@ -1040,7 +1040,7 @@ namespace snd_core
}
}
SysAllocator<coreinit::OSMessage> _queueFrameMsg;
CafeStaticVar<coreinit::OSMessage> _queueFrameMsg{g_sndStaticData};
void AXIst_QueueFrame()
{
+1
View File
@@ -2,6 +2,7 @@
#include "Cafe/OS/libs/snd_core/ax_internal.h"
#include "Cafe/HW/MMU/MMU.h"
#include "config/ActiveSettings.h"
#include "Common/CafeStaticVar.h"
void mic_updateOnAXFrame();
+2 -1
View File
@@ -1,12 +1,13 @@
#include "Cafe/OS/libs/snd_core/ax.h"
#include "Cafe/OS/libs/snd_core/ax_internal.h"
#include "Cafe/HW/MMU/MMU.h"
#include "Common/CafeStaticVar.h"
namespace snd_core
{
static_assert(sizeof(AXVPBMULTI) == 0x20, "");
SysAllocator<AXVPBMULTI, AX_MAX_VOICES> _buffer__AXVPBMultiVoiceArray;
CafeStaticVar<AXVPBMULTI, AX_MAX_VOICES> _buffer__AXVPBMultiVoiceArray{g_sndStaticData};
AXVPBMULTI* __AXVPBMultiVoiceArray;
void AXMultiVoice_Init()
+3 -4
View File
@@ -1,9 +1,8 @@
#include "Cafe/OS/libs/snd_core/ax.h"
#include "Cafe/OS/libs/snd_core/ax_internal.h"
#include "Cafe/HW/MMU/MMU.h"
#include "audio/IAudioAPI.h"
//#include "ax.h"
#include "config/CemuConfig.h"
#include "Common/CafeStaticVar.h"
namespace snd_core
{
@@ -140,8 +139,8 @@ namespace snd_core
_AXOutInitDeviceModes();
}
extern SysAllocator<sint32, AX_SAMPLES_MAX * AX_TV_CHANNEL_COUNT> __AXTVBuffer48;
extern SysAllocator<sint32, AX_SAMPLES_MAX* AX_DRC_CHANNEL_COUNT * 2> __AXDRCBuffer48;
extern CafeStaticVar<sint32, AX_SAMPLES_MAX * AX_TV_CHANNEL_COUNT> __AXTVBuffer48;
extern CafeStaticVar<sint32, AX_SAMPLES_MAX* AX_DRC_CHANNEL_COUNT * 2> __AXDRCBuffer48;
sint16 __buf_AXTVDMABuffers_0[AX_SAMPLES_MAX * AX_TV_CHANNEL_COUNT];
sint16 __buf_AXTVDMABuffers_1[AX_SAMPLES_MAX * AX_TV_CHANNEL_COUNT];
+4 -4
View File
@@ -83,16 +83,16 @@ namespace snd_core
__AXVoicesPerPriority[i].clear();
}
SysAllocator<AXVPBInternal_t, AX_MAX_VOICES> _buffer__AXVPBInternalVoiceArray;
CafeStaticVar<AXVPBInternal_t, AX_MAX_VOICES> _buffer__AXVPBInternalVoiceArray{g_sndStaticData};
AXVPBInternal_t* __AXVPBInternalVoiceArray;
SysAllocator<AXVPBInternal_t, AX_MAX_VOICES> _buffer__AXVPBInternalVoiceShadowCopyArray;
CafeStaticVar<AXVPBInternal_t, AX_MAX_VOICES> _buffer__AXVPBInternalVoiceShadowCopyArray{g_sndStaticData};
AXVPBInternal_t* __AXVPBInternalVoiceShadowCopyArrayPtr; // this is the array used by audio mixing (it's synced at the beginning of every audio frame with __AXVPBInternalVoiceArray)
SysAllocator<AXVPBItd, AX_MAX_VOICES> _buffer__AXVPBItdArray;
CafeStaticVar<AXVPBItd, AX_MAX_VOICES> _buffer__AXVPBItdArray{g_sndStaticData};
AXVPBItd* __AXVPBItdArrayPtr;
SysAllocator<AXVPB, AX_MAX_VOICES> _buffer__AXVPBArray;
CafeStaticVar<AXVPB, AX_MAX_VOICES> _buffer__AXVPBArray{g_sndStaticData};
AXVPB* __AXVPBArrayPtr;
struct AXUSERPROTECTION
+13 -9
View File
@@ -8,6 +8,8 @@
#include "util/helpers/helpers.h"
#include "resource/IconsFontAwesome5.h"
constinit COSStaticData s_swkbdStaticData;
#define SWKBD_FORM_STRING_MAX_LENGTH (4096) // counted in 16-bit characters
#define SWKBD_STATE_BLANK (0) // not visible
@@ -85,18 +87,14 @@ typedef struct
bool cancelState;
}swkbdInternalState_t;
swkbdInternalState_t* swkbdInternalState = nullptr;
sint32 isNeedCalcSubThreadFont = 0;
sint32 isNeedCalcSubThreadPredict = 0;
CafeStaticVar<swkbdInternalState_t> swkbdInternalState{s_swkbdStaticData};
void SwkbdCreate(uint8* workMemory, uint32 regionType, uint32 unk, coreinit::FSClient_t* fsClient)
{
if( swkbdInternalState == nullptr )
{
MPTR swkbdInternalStateMPTR = coreinit_allocFromSysArea(sizeof(swkbdInternalState_t), 4);
swkbdInternalState = (swkbdInternalState_t*)memory_getPointerFromVirtualOffset(swkbdInternalStateMPTR);
memset(swkbdInternalState, 0x00, sizeof(swkbdInternalState_t));
}
memset(swkbdInternalState.GetPtr(), 0, sizeof(swkbdInternalState_t));
coreinit::OSSleepTicks(ESPRESSO_TIMER_CLOCK); // simulate this function taking a bit of time to run. MH3U/MH3G requires this to not softlock
// pretend that there is some work to do
isNeedCalcSubThreadFont = 3;
@@ -574,7 +572,7 @@ typedef struct
uint32be endIndex;
}changeStringParam_t;
SysAllocator<changeStringParam_t> _changeStringParam;
CafeStaticVar<changeStringParam_t> _changeStringParam{s_swkbdStaticData};
void swkbd_inputStringChanged()
{
@@ -679,8 +677,14 @@ namespace swkbd
return "swkbd";
}
void RPLUnmapped() override
{
s_swkbdStaticData.Deallocate();
}
void RPLMapped() override
{
s_swkbdStaticData.Allocate();
cafeExportRegisterFunc(SwkbdCreate, "swkbd", "SwkbdCreate__3RplFPUcQ3_2nn5swkbd10RegionTypeUiP8FSClient", LogType::SWKBD);
cafeExportRegisterFunc(SwkbdCalc, "swkbd", "SwkbdCalc__3RplFRCQ3_2nn5swkbd14ControllerInfo", LogType::SWKBD);
cafeExportRegisterFunc(SwkbdGetStateKeyboard, "swkbd", "SwkbdGetStateKeyboard__3RplFv", LogType::SWKBD);
@@ -704,7 +708,7 @@ namespace swkbd
{
if (reason == coreinit::RplEntryReason::Loaded)
{
swkbdInternalState = nullptr;
}
else if (reason == coreinit::RplEntryReason::Unloaded)
{
+16 -1
View File
@@ -50,6 +50,8 @@
extern bool isLaunchTypeELF;
constinit COSStaticData s_vpadStaticData;
VPADDir g_vpadGyroDirOverwrite[VPAD_MAX_CONTROLLERS] =
{
{{1.0f,0.0f,0.0f}, {0.0f,1.0f,0.0f}, {0.0f, 0.0f, 0.1f}},
@@ -162,7 +164,7 @@ namespace vpad
struct
{
SysAllocator<coreinit::OSAlarm_t> alarm;
CafeStaticVar<coreinit::OSAlarm_t> alarm{s_vpadStaticData};
struct
{
@@ -1169,8 +1171,21 @@ namespace vpad
return "vpad";
}
void RPLUnmapped() override
{
coreinit::OSCancelAlarm(g_vpad.alarm.GetPtr());
s_vpadStaticData.Deallocate();
}
void rpl_entry(uint32 moduleHandle, coreinit::RplEntryReason reason) override
{
if (reason == coreinit::RplEntryReason::Loaded)
start();
}
void RPLMapped() override
{
s_vpadStaticData.Allocate();
cafeExportRegister("vpad", VPADSetBtnRepeat, LogType::InputAPI);
cafeExportRegister("vpad", VPADSetSamplingCallback, LogType::InputAPI);
cafeExportRegister("vpad", VPADRead, LogType::InputAPI);
+2
View File
@@ -1,5 +1,7 @@
add_library(CemuCommon
betype.h
CafeStaticVar.cpp
CafeStaticVar.h
cpu_features.cpp
cpu_features.h
enumFlags.h
+120
View File
@@ -0,0 +1,120 @@
#include "CafeStaticVar.h"
#include "Cafe/HW/MMU/MMU.h"
#include "util/ChunkedHeap/ChunkedHeap.h"
namespace
{
uint32 AlignOffset(uint32 offset, uint32 alignment)
{
cemu_assert_debug((offset+alignment) >= offset);
uint64 aligned = (offset + alignment - 1u) & ~(alignment - 1u);
return static_cast<uint32>(aligned);
}
std::unique_ptr<VHeap> s_iosuStaticDataHeap{};
std::set<CafeStaticData*> s_iosuStaticDataBlocks;
std::mutex s_cafeStaticDataMutex;
}
CafeStaticVarBase::CafeStaticVarBase(CafeStaticData& owner, uint32 size, uint32 alignment)
: m_owner(&owner), m_size(size), m_alignment(alignment)
{
std::unique_lock _l(s_cafeStaticDataMutex);
if (!owner.m_vars)
owner.m_vars = new std::vector<CafeStaticVarBase*>();
owner.m_vars->push_back(this);
}
CafeStaticVarBase::~CafeStaticVarBase()
{
std::unique_lock _l(s_cafeStaticDataMutex);
if (m_owner)
{
cemu_assert(!m_owner->IsAllocated());
std::erase(*m_owner->m_vars, this);
}
}
bool CafeStaticData::HasAnyAllocations()
{
std::unique_lock _l(s_cafeStaticDataMutex);
return !s_iosuStaticDataBlocks.empty();
}
MPTR coreinit_allocFromSysArea(uint32 size, uint32 alignment);
void coreinit_freeToSysArea(MPTR mem);
void CafeStaticData::Allocate()
{
std::unique_lock _l(s_cafeStaticDataMutex);
if (!m_vars)
return; // empty
// register this static block
cemu_assert_debug(!s_iosuStaticDataBlocks.contains(this));
s_iosuStaticDataBlocks.emplace(this);
// calculate total allocation size
uint32 size = 0;
uint32 alignment = 32;
for (auto& var : *m_vars)
{
size = AlignOffset(size, var->m_alignment);
cemu_assert(var->m_size < 1024 * 1024 * 128); // sanity check size
size += var->m_size;
alignment = std::max(alignment, var->m_alignment);
}
cemu_assert_debug(size > 0); // zero sized variables are not allowed
// get heap
VHeap* heap = nullptr;
if (m_mode == Mode::IOSU)
{
cemu_assert(mmuRange_IOSU_AREA.isMapped());
if (!s_iosuStaticDataHeap)
s_iosuStaticDataHeap = std::make_unique<VHeap>(mmuRange_IOSU_AREA.getPtr(), mmuRange_IOSU_AREA.getSize());
heap = s_iosuStaticDataHeap.get();
m_allocation = heap->alloc(size, alignment);
}
else if (m_mode == Mode::COS)
{
MPTR allocOffset = coreinit_allocFromSysArea(size, alignment);
cemu_assert(allocOffset != MPTR_NULL);
m_allocation = MEMPTR<void>(allocOffset).GetPtr();
}
cemu_assert(m_allocation);
uint32 offset = 0;
for (auto& var : *m_vars)
{
offset = AlignOffset(offset, var->m_alignment);
var->m_memory = static_cast<uint8*>(m_allocation) + offset;
offset += var->m_size;
}
for (auto& var : *m_vars)
var->Initialize();
}
void CafeStaticData::Deallocate()
{
std::unique_lock _l(s_cafeStaticDataMutex);
if (!m_vars)
return; // empty
cemu_assert(m_allocation);
for (auto& var : *m_vars)
var->m_memory = nullptr;
if (m_mode == Mode::IOSU)
{
s_iosuStaticDataHeap->free(m_allocation);
}
else // COS
{
coreinit_freeToSysArea(MEMPTR<void>(m_allocation).GetMPTR());
}
m_allocation = nullptr;
s_iosuStaticDataBlocks.erase(this);
}
CafeStaticData::~CafeStaticData()
{
std::unique_lock _l(s_cafeStaticDataMutex);
for (auto& it : *m_vars)
it->m_owner = nullptr;
delete m_vars;
}
+164
View File
@@ -0,0 +1,164 @@
#pragma once
class CafeStaticVarBase;
class CafeStaticData
{
protected:
enum class Mode : uint8
{
COS = 0,
IOSU = 1
};
constexpr CafeStaticData(Mode mode) : m_mode(mode) {};
CafeStaticData(const CafeStaticData&) = delete;
CafeStaticData& operator=(const CafeStaticData&) = delete;
~CafeStaticData();
public:
void Allocate();
void Deallocate();
bool IsAllocated() const { return m_allocation != nullptr; }
static bool HasAnyAllocations();
private:
friend class CafeStaticVarBase;
std::vector<CafeStaticVarBase*>* m_vars{}; // pointer to make this class constinit compatible
void* m_allocation{};
Mode m_mode;
};
class CafeStaticVarBase
{
public:
CafeStaticVarBase(const CafeStaticVarBase&) = delete;
CafeStaticVarBase& operator=(const CafeStaticVarBase&) = delete;
protected:
CafeStaticVarBase(CafeStaticData& owner, uint32 size, uint32 alignment);
virtual ~CafeStaticVarBase();
MEMPTR<void> m_memory;
private:
friend class CafeStaticData;
virtual void Initialize() = 0;
CafeStaticData* m_owner{};
CafeStaticVarBase* m_next{};
uint32 m_size;
uint32 m_alignment;
};
template<typename T, size_t count = 1, size_t alignment = 32>
class CafeStaticVar : public CafeStaticVarBase
{
static_assert(count > 0 && count <= std::numeric_limits<uint32>::max() / sizeof(T));
static_assert(alignment > 0 && (alignment & (alignment - 1)) == 0);
static_assert(alignment >= alignof(T) && alignment <= 0x400000);
static_assert(std::is_trivially_copyable_v<T> && std::is_trivially_destructible_v<T>);
static_assert(!std::is_const_v<T>);
public:
explicit CafeStaticVar(CafeStaticData& owner) : CafeStaticVarBase(owner, GetByteSize(), alignment)
{
cemu_assert_debug(!owner.IsAllocated());
}
CafeStaticVar(CafeStaticData& owner, const T& value) requires(count == 1) : CafeStaticVar(owner)
{
cemu_assert_debug(!owner.IsAllocated());
m_initializer = [value](T* ptr) { std::construct_at(ptr, value); };
}
CafeStaticVar(CafeStaticData& owner, std::initializer_list<T> values) requires(count != 1) : CafeStaticVar(owner)
{
cemu_assert_debug(!owner.IsAllocated());
cemu_assert(values.size() <= count);
std::array<T, count> initial{};
std::copy(values.begin(), values.end(), initial.begin());
m_initializer = [initial](T* ptr) { std::uninitialized_copy_n(initial.data(), count, ptr); };
}
template<size_t N>
CafeStaticVar(CafeStaticData& owner, const char (&value)[N]) requires(std::is_same_v<T, char>) : CafeStaticVar(owner)
{
cemu_assert_debug(!owner.IsAllocated());
static_assert(N <= count);
std::array<char, count> initial{};
std::copy_n(value, N, initial.begin());
m_initializer = [initial](T* ptr) { std::uninitialized_copy_n(initial.data(), count, ptr); };
}
template<typename F>
CafeStaticVar(CafeStaticData& owner, F initializer) requires(count == 1 && std::is_invocable_r_v<T, F&>) : CafeStaticVar(owner)
{
cemu_assert_debug(!owner.IsAllocated());
m_initializer = [initializer](T* ptr) mutable { std::construct_at(ptr, initializer()); };
}
static constexpr uint32 GetCount() { return static_cast<uint32>(count); }
static constexpr uint32 GetByteSize() { return static_cast<uint32>(sizeof(T) * count); }
bool IsAllocated() const { return !m_memory.IsNull(); }
uint32 GetMPTR() const { return m_memory.GetMPTR(); }
T* GetPtr() const { return static_cast<T*>(m_memory.GetPtr()); }
CafeStaticVar& operator=(const T& value) requires(count == 1)
{
*CheckedPtr() = value;
return *this;
}
operator T() const requires(count == 1) { return *CheckedPtr(); }
operator T*() const { return GetPtr(); }
T& operator*() const { return *CheckedPtr(); }
T* operator->() const requires(count == 1) { return CheckedPtr(); }
T* operator&() const requires(count == 1) { return GetPtr(); }
T& operator[](size_t index) const
{
cemu_assert(index < count);
return CheckedPtr()[index];
}
T* operator+(sint32 offset) const { return CheckedPtr() + offset; }
T* operator-(sint32 offset) const { return CheckedPtr() - offset; }
private:
T* CheckedPtr() const
{
cemu_assert_debug(IsAllocated());
return GetPtr();
}
void Initialize() override
{
if (m_initializer)
m_initializer(GetPtr());
else
std::uninitialized_value_construct_n(GetPtr(), count);
}
std::function<void(T*)> m_initializer;
};
template<size_t N>
CafeStaticVar(CafeStaticData&, const char (&)[N]) -> CafeStaticVar<char, N>;
// IOSU storage
class IOSUStaticData : public CafeStaticData
{
public:
constexpr IOSUStaticData() : CafeStaticData(CafeStaticData::Mode::IOSU)
{
}
};
// COS storage
class COSStaticData : public CafeStaticData
{
public:
constexpr COSStaticData() : CafeStaticData(CafeStaticData::Mode::COS)
{
}
};
+1
View File
@@ -372,6 +372,7 @@ public:
void free(void* addr) override
{
cemu_assert_debug(addr >= m_heapBase && addr < (m_heapBase + m_heapSize));
_free((uint32)((uint8*)addr - (uint8*)m_heapBase));
}