diff --git a/sysmodules/rosalina/source/plugin/memoryblock.c b/sysmodules/rosalina/source/plugin/memoryblock.c deleted file mode 100644 index a5022992..00000000 --- a/sysmodules/rosalina/source/plugin/memoryblock.c +++ /dev/null @@ -1,281 +0,0 @@ -#include <3ds.h> -#include -#include -#include "plugin.h" -#include "ifile.h" -#include "utils.h" - -#define MEMPERM_RW (MEMPERM_READ | MEMPERM_WRITE) - -u32 g_loadSaveSwapArgs[4]; -char g_swapFileName[256]; -u32 g_memBlockSize = 5 * 1024 * 1024; - -Result MemoryBlock__SetSize(u32 size) { - PluginLoaderContext *ctx = &PluginLoaderCtx; - MemoryBlock *memblock = &ctx->memblock; - - if (memblock->isReady) - return MAKERESULT(RL_PERMANENT, RS_INVALIDSTATE, RM_LDR, RD_ALREADY_INITIALIZED); - - g_memBlockSize = size; - return 0; -} - -Result MemoryBlock__IsReady(void) -{ - PluginLoaderContext *ctx = &PluginLoaderCtx; - MemoryBlock *memblock = &ctx->memblock; - - if (memblock->isReady) - return 0; - - Result res; - - if (isN3DS || (ctx->pluginMemoryStrategy == PLG_STRATEGY_MODE3)) - { - s64 appRegionSize = 0; - s64 appRegionUsed = 0; - u32 appRegionFree; - u32 gameReserveSize; - vu32* appMemAllocPtr = (vu32 *)PA_FROM_VA_PTR(0x1FF80040); - u32 appMemAlloc = *appMemAllocPtr; - u32 temp; - - memblock->isAppRegion = true; - - svcGetSystemInfo(&appRegionSize, 0x10000, 0x80); - svcGetSystemInfo(&appRegionUsed, 0, 1); - - appRegionFree = appRegionSize - appRegionUsed; - - // Check if appmemalloc reports the entire available memory - if ((u32)appRegionSize == appMemAlloc) - *appMemAllocPtr -= g_memBlockSize; ///< Remove plugin share from available memory - - gameReserveSize = appRegionFree - g_memBlockSize; - - // First reserve the game memory size (to avoid heap relocation) - res = svcControlMemoryUnsafe((u32 *)&temp, 0x30000000, - gameReserveSize, MEMOP_REGION_APP | MEMOP_ALLOC | MEMOP_LINEAR_FLAG, MEMPERM_RW); - - // Then allocate our plugin memory block - if (R_SUCCEEDED(res)) - res = svcControlMemoryUnsafe((u32 *)&memblock->memblock, 0x07000000, - g_memBlockSize, MEMOP_REGION_APP | MEMOP_ALLOC | MEMOP_LINEAR_FLAG, MEMPERM_RW); - - // Finally release game reserve block - if (R_SUCCEEDED(res)) - res = svcControlMemoryUnsafe((u32 *)&temp, temp, gameReserveSize, MEMOP_FREE, 0); - } - else - { - memblock->isAppRegion = false; - res = svcControlMemoryUnsafe((u32 *)&memblock->memblock, 0x07000000, - g_memBlockSize, MEMOP_REGION_SYSTEM | MEMOP_ALLOC | MEMOP_LINEAR_FLAG, MEMPERM_RW); - } - - if (R_FAILED(res)) { - if (isN3DS || (ctx->pluginMemoryStrategy == PLG_STRATEGY_MODE3)) - PluginLoader__Error("Cannot map plugin memory.", res); - else - PluginLoader__Error("A console reboot is needed to\nclose extended memory games.\n\nPress [B] to reboot.", res); - svcKernelSetState(7); - } - else - { - // Clear the memblock - memset(memblock->memblock, 0, g_memBlockSize); - memblock->isReady = true; - - /*if (isN3DS) - { - // Check if appmemalloc reports the entire available memory - s64 appRegionSize = 0; - vu32* appMemAlloc = (vu32 *)PA_FROM_VA_PTR(0x1FF80040); - - svcGetSystemInfo(&appRegionSize, 0x10000, 0x80); - if ((u32)appRegionSize == *appMemAlloc) - *appMemAlloc -= g_memBlockSize; ///< Remove plugin share from available memory - } */ - } - - return res; -} - -Result MemoryBlock__Free(void) -{ - MemoryBlock *memblock = &PluginLoaderCtx.memblock; - - if (!memblock->isReady) - return 0; - - MemOp memRegion = memblock->isAppRegion ? MEMOP_REGION_APP : MEMOP_REGION_SYSTEM; - Result res = svcControlMemoryUnsafe((u32 *)&memblock->memblock, (u32)memblock->memblock, - g_memBlockSize, memRegion | MEMOP_FREE, 0); - - memblock->isReady = false; - memblock->memblock = NULL; - - if (R_FAILED(res)) - PluginLoader__Error("Couldn't free memblock", res); - - return res; -} - -#define FS_OPEN_RWC (FS_OPEN_READ | FS_OPEN_WRITE | FS_OPEN_CREATE) - -Result MemoryBlock__ToSwapFile(void) -{ - MemoryBlock *memblock = &PluginLoaderCtx.memblock; - PluginLoaderContext *ctx = &PluginLoaderCtx; - - u64 written = 0; - u64 toWrite = g_memBlockSize; - IFile file; - Result res = 0; - - svcFlushDataCacheRange(memblock->memblock, g_memBlockSize); - res = IFile_Open(&file, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, ""), - fsMakePath(PATH_ASCII, g_swapFileName), FS_OPEN_RWC); - - if (R_FAILED(res)) { - PluginLoader__Error("CRITICAL: Failed to open swap file.\n\nConsole will now reboot.", res); - svcKernelSetState(7); - } - - if (!ctx->isSwapFunctionset) { - PluginLoader__Error("CRITICAL: Swap save function\nis not set.\n\nConsole will now reboot.", res); - svcKernelSetState(7); - } - ctx->swapLoadChecksum = saveSwapFunc(memblock->memblock, memblock->memblock + g_memBlockSize, g_loadSaveSwapArgs); - - res = IFile_Write(&file, &written, memblock->memblock, toWrite, FS_WRITE_FLUSH); - - if (R_FAILED(res) || written != toWrite) { - PluginLoader__Error("CRITICAL: Couldn't write swap to SD.\n\nConsole will now reboot.", res); - svcKernelSetState(7); - } - - IFile_Close(&file); - return res; -} - -Result MemoryBlock__FromSwapFile(void) -{ - MemoryBlock *memblock = &PluginLoaderCtx.memblock; - - u64 read = 0; - u64 toRead = g_memBlockSize; - IFile file; - Result res = 0; - - res = IFile_Open(&file, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, ""), - fsMakePath(PATH_ASCII, g_swapFileName), FS_OPEN_READ); - - if (R_FAILED(res)) { - PluginLoader__Error("CRITICAL: Failed to open swap file.\n\nConsole will now reboot.", res); - svcKernelSetState(7); - } - - res = IFile_Read(&file, &read, memblock->memblock, toRead); - - if (R_FAILED(res) || read != toRead) { - PluginLoader__Error("CRITICAL: Couldn't read swap from SD.\n\nConsole will now reboot.", res); - svcKernelSetState(7); - } - - u32 checksum = loadSwapFunc(memblock->memblock, memblock->memblock + g_memBlockSize, g_loadSaveSwapArgs); - - PluginLoaderContext *ctx = &PluginLoaderCtx; - if (checksum != ctx->swapLoadChecksum) { - res = -1; - PluginLoader__Error("CRITICAL: Swap file is corrupted.\n\nConsole will now reboot.", res); - svcKernelSetState(7); - } - - svcFlushDataCacheRange(memblock->memblock, g_memBlockSize); - IFile_Close(&file); - return res; -} - -Result MemoryBlock__MountInProcess(void) -{ - Handle target = PluginLoaderCtx.target; - Error *error = &PluginLoaderCtx.error; - PluginHeader *header = &PluginLoaderCtx.header; - MemoryBlock *memblock = &PluginLoaderCtx.memblock; - - Result res = 0; - - // Executable - if (R_FAILED((res = svcMapProcessMemoryEx(target, 0x07000000, CUR_PROCESS_HANDLE, (u32)memblock->memblock, header->exeSize)))) - { - error->message = "Couldn't map exe memory block"; - error->code = res; - return res; - } - - // Heap (to be used by the plugin) - if (R_FAILED((res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32)memblock->memblock + header->exeSize, header->heapSize)))) - { - error->message = "Couldn't map heap memory block"; - error->code = res; - } - - return res; -} - -Result MemoryBlock__UnmountFromProcess(void) -{ - Handle target = PluginLoaderCtx.target; - PluginHeader *header = &PluginLoaderCtx.header; - - Result res = 0; - - res = svcUnmapProcessMemoryEx(target, 0x07000000, header->exeSize); - res |= svcUnmapProcessMemoryEx(target, header->heapVA, header->heapSize); - - return res; -} - -Result MemoryBlock__SetSwapSettings(u32* func, bool isLoad, u32* params) -{ - u32* physAddr = PA_FROM_VA_PTR(isLoad ? (u32)loadSwapFunc : (u32)saveSwapFunc); //Bypass mem permissions - - memcpy(g_loadSaveSwapArgs, params, sizeof(g_loadSaveSwapArgs)); - - int i = 0; - for (; i < 32 && func[i] != 0xE320F000; i++) - physAddr[i] = func[i]; - - if (i >= 32) { - return -1; - } - return 0; -} - -void MemoryBlock__ResetSwapSettings(void) -{ - u32* savePhysAddr = PA_FROM_VA_PTR((u32)saveSwapFunc); //Bypass mem permissions - u32* loadPhysAddr = PA_FROM_VA_PTR((u32)loadSwapFunc); - PluginLoaderContext *ctx = &PluginLoaderCtx; - - memset(g_loadSaveSwapArgs, 0, sizeof(g_loadSaveSwapArgs)); - - savePhysAddr[0] = loadPhysAddr[0] = 0xE12FFF1E; // BX LR - - for (int i = 1; i < 32; i++) { - savePhysAddr[i] = loadPhysAddr[i] = 0xE320F000; // NOP - } - - strcpy(g_swapFileName, "/luma/plugins/.swap"); - ctx->isSwapFunctionset = false; - - svcInvalidateEntireInstructionCache(); -} - -PluginHeader* MemoryBlock__GetMappedPluginHeader() { - MemoryBlock *memblock = &PluginLoaderCtx.memblock; - return memblock->isReady ? (PluginHeader*)memblock->memblock : NULL; -}