mirror of
https://github.com/cemu-project/Cemu.git
synced 2026-10-31 03:26:50 +01:00
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:
1 parent
d46466cd51
commit
bb28394ce1
65 files changed
+804
-234
No files matched your search
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
};
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -12,8 +12,11 @@
|
||||
|
||||
// general
|
||||
|
||||
class COSStaticData;
|
||||
|
||||
namespace GX2
|
||||
{
|
||||
extern COSStaticData s_gx2StaticData;
|
||||
COSModule* GetModule();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
add_library(CemuCommon
|
||||
betype.h
|
||||
CafeStaticVar.cpp
|
||||
CafeStaticVar.h
|
||||
cpu_features.cpp
|
||||
cpu_features.h
|
||||
enumFlags.h
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user