diff options
author | RSDuck <RSDuck@users.noreply.github.com> | 2020-07-04 18:58:00 +0200 |
---|---|---|
committer | RSDuck <RSDuck@users.noreply.github.com> | 2020-07-04 18:58:00 +0200 |
commit | 778623a8b7ded3a66fc838840ce85626f5feed05 (patch) | |
tree | 1fc317f4aa173cc9933c74163756103c2e67e0bb | |
parent | 62c6e2f703d88660e0ca9bda78032c5bd6b63a78 (diff) |
make linux work and fix a few bugs
-rw-r--r-- | src/ARMJIT.cpp | 8 | ||||
-rw-r--r-- | src/ARMJIT_Memory.cpp | 121 | ||||
-rw-r--r-- | src/ARMJIT_x64/ARMJIT_LoadStore.cpp | 22 | ||||
-rw-r--r-- | src/NDS.cpp | 1 | ||||
-rw-r--r-- | src/frontend/qt_sdl/EmuSettingsDialog.cpp | 5 | ||||
-rw-r--r-- | src/frontend/qt_sdl/EmuSettingsDialog.h | 2 | ||||
-rw-r--r-- | src/frontend/qt_sdl/main.cpp | 7 |
7 files changed, 136 insertions, 30 deletions
diff --git a/src/ARMJIT.cpp b/src/ARMJIT.cpp index 2a61c38..0a0b52f 100644 --- a/src/ARMJIT.cpp +++ b/src/ARMJIT.cpp @@ -86,9 +86,9 @@ const u32 CodeRegionSizes[ARMJIT_Memory::memregions_Count] = 0x40000, 0x10000, 0x10000, - sizeof(DSi::NWRAM_A), - sizeof(DSi::NWRAM_B), - sizeof(DSi::NWRAM_C), + DSi::NWRAMSize, + DSi::NWRAMSize, + DSi::NWRAMSize, }; AddressRange* const CodeMemRegions[ARMJIT_Memory::memregions_Count] = @@ -964,6 +964,7 @@ void CompileBlock(ARM* cpu) block = prevBlock; } + assert((localAddr & 1) == 0); for (int j = 0; j < numAddressRanges; j++) { assert(addressRanges[j] == block->AddressRanges()[j]); @@ -1011,6 +1012,7 @@ void InvalidateByAddr(u32 localAddr) { mask = block->AddressMasks()[j]; invalidated = block->AddressMasks()[j] & mask; + assert(mask); break; } } diff --git a/src/ARMJIT_Memory.cpp b/src/ARMJIT_Memory.cpp index 0276c65..4a8b8a5 100644 --- a/src/ARMJIT_Memory.cpp +++ b/src/ARMJIT_Memory.cpp @@ -2,6 +2,12 @@ #include "switch/compat_switch.h" #elif defined(_WIN32) #include <windows.h> +#else +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <signal.h> #endif #include "ARMJIT_Memory.h" @@ -119,6 +125,45 @@ static LONG ExceptionHandler(EXCEPTION_POINTERS* exceptionInfo) return EXCEPTION_CONTINUE_SEARCH; } +#else + +struct sigaction NewSa; +struct sigaction OldSa; + +static void SigsegvHandler(int sig, siginfo_t* info, void* rawContext) +{ + ucontext_t* context = (ucontext_t*)rawContext; + + ARMJIT_Memory::FaultDescription desc; + u8* curArea = (u8*)(NDS::CurCPU == 0 ? ARMJIT_Memory::FastMem9Start : ARMJIT_Memory::FastMem7Start); + desc.EmulatedFaultAddr = (u8*)info->si_addr - curArea; + desc.FaultPC = context->uc_mcontext.gregs[REG_RIP]; + + s32 offset = 0; + if (ARMJIT_Memory::FaultHandler(&desc, offset)) + { + context->uc_mcontext.gregs[REG_RIP] += offset; + return; + } + + if (OldSa.sa_flags & SA_SIGINFO) + { + OldSa.sa_sigaction(sig, info, rawContext); + return; + } + if (OldSa.sa_handler == SIG_DFL) + { + signal(sig, SIG_DFL); + return; + } + if (OldSa.sa_handler == SIG_IGN) + { + // Ignore signal + return; + } + OldSa.sa_handler(sig); +} + #endif namespace ARMJIT_Memory @@ -187,6 +232,9 @@ u8* MemoryBaseCodeMem; u8* MemoryBase; HANDLE MemoryFile; LPVOID ExceptionHandlerHandle; +#else +u8* MemoryBase; +int MemoryFile; #endif bool MapIntoRange(u32 addr, u32 num, u32 offset, u32 size) @@ -199,6 +247,8 @@ bool MapIntoRange(u32 addr, u32 num, u32 offset, u32 size) #elif defined(_WIN32) bool r = MapViewOfFileEx(MemoryFile, FILE_MAP_READ | FILE_MAP_WRITE, 0, offset, size, dst) == dst; return r; +#else + return mmap(dst, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, MemoryFile, offset) != MAP_FAILED; #endif } @@ -209,8 +259,10 @@ bool UnmapFromRange(u32 addr, u32 num, u32 offset, u32 size) Result r = svcUnmapProcessMemory(dst, envGetOwnProcessHandle(), (u64)(MemoryBaseCodeMem + offset), size); return R_SUCCEEDED(r); -#else +#elif defined(_WIN32) return UnmapViewOfFile(dst); +#else + return munmap(dst, size) == 0; #endif } @@ -226,6 +278,15 @@ void SetCodeProtectionRange(u32 addr, u32 size, u32 num, int protection) else winProtection = PAGE_READWRITE; VirtualProtect(dst, size, winProtection, &oldProtection); +#else + int posixProt; + if (protection == 0) + posixProt = PROT_NONE; + else if (protection == 1) + posixProt = PROT_READ; + else + posixProt = PROT_READ | PROT_WRITE; + mprotect(dst, size, posixProt); #endif } @@ -270,8 +331,9 @@ struct Mapping #endif } } -#if defined(_WIN32) - UnmapFromRange(Addr, Num, OffsetsPerRegion[region] + LocalOffset, Size); +#ifndef __SWITCH__ + bool succeded = UnmapFromRange(Addr, Num, OffsetsPerRegion[region] + LocalOffset, Size); + assert(succeded); #endif } }; @@ -308,7 +370,7 @@ void SetCodeProtection(int region, u32 offset, bool protect) else success = MapIntoRange(effectiveAddr, mapping.Num, OffsetsPerRegion[region] + offset, 0x1000); assert(success); -#elif defined(_WIN32) +#else SetCodeProtectionRange(effectiveAddr, 0x1000, mapping.Num, protect ? 1 : 2); #endif } @@ -418,18 +480,16 @@ bool MapAtAddress(u32 addr) if (!IsFastmemCompatible(region)) return false; - return false; - u32 mirrorStart, mirrorSize, memoryOffset; bool isMapped = GetMirrorLocation(region, num, addr, memoryOffset, mirrorStart, mirrorSize); if (!isMapped) return false; u8* states = num == 0 ? MappingStatus9 : MappingStatus7; - printf("trying to create mapping %x, %x %d %d\n", mirrorStart, mirrorSize, region, num); + printf("trying to create mapping %x, %x %x %d %d\n", mirrorStart, mirrorSize, memoryOffset, region, num); bool isExecutable = ARMJIT::CodeMemRegions[region]; -#if defined(_WIN32) +#ifndef __SWITCH__ bool succeded = MapIntoRange(mirrorStart, num, OffsetsPerRegion[region] + memoryOffset, mirrorSize); assert(succeded); #endif @@ -469,10 +529,10 @@ bool MapAtAddress(u32 addr) bool succeded = MapIntoRange(mirrorStart + sectionOffset, num, sectionOffset + memoryOffset + OffsetsPerRegion[region], sectionSize); assert(succeded); } -#elif defined(_WIN32) +#else if (hasCode) { - SetCodeProtectionRange(mirrorStart + offset, sectionSize, num, 1); + SetCodeProtectionRange(mirrorStart + sectionOffset, sectionSize, num, 1); } #endif } @@ -509,6 +569,8 @@ bool FaultHandler(FaultDescription* faultDesc, s32& offset) void Init() { + const u64 AddrSpaceSize = 0x100000000; + #if defined(__SWITCH__) MemoryBase = (u8*)memalign(0x1000, MemoryTotalSize); MemoryBaseCodeMem = (u8*)virtmemReserve(MemoryTotalSize); @@ -521,9 +583,9 @@ void Init() assert(succeded); // 8 GB of address space, just don't ask... - FastMem9Start = virtmemReserve(0x100000000); + FastMem9Start = virtmemReserve(AddrSpaceSize); assert(FastMem9Start); - FastMem7Start = virtmemReserve(0x100000000); + FastMem7Start = virtmemReserve(AddrSpaceSize); assert(FastMem7Start); u8* basePtr = MemoryBaseCodeMem; @@ -534,8 +596,8 @@ void Init() MemoryBase = (u8*)VirtualAlloc(NULL, MemoryTotalSize, MEM_RESERVE, PAGE_READWRITE); - FastMem9Start = VirtualAlloc(NULL, 0x100000000, MEM_RESERVE, PAGE_READWRITE); - FastMem7Start = VirtualAlloc(NULL, 0x100000000, MEM_RESERVE, PAGE_READWRITE); + FastMem9Start = VirtualAlloc(NULL, AddrSpaceSize, MEM_RESERVE, PAGE_READWRITE); + FastMem7Start = VirtualAlloc(NULL, AddrSpaceSize, MEM_RESERVE, PAGE_READWRITE); // only free them after they have all been reserved // so they can't overlap @@ -546,6 +608,27 @@ void Init() MapViewOfFileEx(MemoryFile, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, MemoryTotalSize, MemoryBase); u8* basePtr = MemoryBase; +#else + FastMem9Start = mmap(NULL, AddrSpaceSize, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0); + FastMem7Start = mmap(NULL, AddrSpaceSize, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0); + + MemoryBase = (u8*)mmap(NULL, MemoryTotalSize, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0); + + MemoryFile = memfd_create("melondsfastmem", 0); + ftruncate(MemoryFile, MemoryTotalSize); + + NewSa.sa_flags = SA_SIGINFO; + sigemptyset(&NewSa.sa_mask); + NewSa.sa_sigaction = SigsegvHandler; + sigaction(SIGSEGV, &NewSa, &OldSa); + + munmap(MemoryBase, MemoryTotalSize); + munmap(FastMem9Start, AddrSpaceSize); + munmap(FastMem7Start, AddrSpaceSize); + + mmap(MemoryBase, MemoryTotalSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, MemoryFile, 0); + + u8* basePtr = MemoryBase; #endif NDS::MainRAM = basePtr + MemBlockMainRAMOffset; NDS::SharedWRAM = basePtr + MemBlockSWRAMOffset; @@ -604,6 +687,8 @@ bool IsFastmemCompatible(int region) || region == memregion_NewSharedWRAM_C) return false; #endif + if (region == memregion_DTCM) + return false; return OffsetsPerRegion[region] != UINT32_MAX; } @@ -620,6 +705,14 @@ bool GetMirrorLocation(int region, u32 num, u32 addr, u32& memoryOffset, u32& mi return true; } return false; + case memregion_DTCM: + if (num == 0) + { + mirrorStart = addr & ~(DTCMPhysicalSize - 1); + mirrorSize = DTCMPhysicalSize; + return true; + } + return false; case memregion_MainRAM: mirrorStart = addr & ~NDS::MainRAMMask; mirrorSize = NDS::MainRAMMask + 1; diff --git a/src/ARMJIT_x64/ARMJIT_LoadStore.cpp b/src/ARMJIT_x64/ARMJIT_LoadStore.cpp index 2da113b..ff15729 100644 --- a/src/ARMJIT_x64/ARMJIT_LoadStore.cpp +++ b/src/ARMJIT_x64/ARMJIT_LoadStore.cpp @@ -379,19 +379,16 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc AND(32, R(RSCRATCH4), Imm8(~3)); u8* fastPathStart = GetWritableCodePtr(); - u8* firstLoadStoreAddr; - - bool firstLoadStore = true; + u8* loadStoreAddr[16]; MOV(64, R(RSCRATCH2), ImmPtr(Num == 0 ? ARMJIT_Memory::FastMem9Start : ARMJIT_Memory::FastMem7Start)); ADD(64, R(RSCRATCH2), R(RSCRATCH4)); - MOV(32, R(RSCRATCH3), R(RSCRATCH4)); u32 offset = 0; + int i = 0; for (int reg : regs) { - if (firstLoadStore) - firstLoadStoreAddr = GetWritableCodePtr(); + loadStoreAddr[i] = GetWritableCodePtr(); OpArg mem = MDisp(RSCRATCH2, offset); if (store) @@ -403,8 +400,7 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc else { LoadReg(reg, RSCRATCH); - if (firstLoadStore) - firstLoadStoreAddr = GetWritableCodePtr(); + loadStoreAddr[i] = GetWritableCodePtr(); MOV(32, mem, R(RSCRATCH)); } } @@ -421,17 +417,19 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc } } offset += 4; - - firstLoadStore = false; + i++; } LoadStorePatch patch; patch.Size = GetWritableCodePtr() - fastPathStart; - patch.Offset = fastPathStart - firstLoadStoreAddr; SwitchToFarCode(); patch.PatchFunc = GetWritableCodePtr(); - LoadStorePatches[firstLoadStoreAddr] = patch; + for (i = 0; i < regsCount; i++) + { + patch.Offset = fastPathStart - loadStoreAddr[i]; + LoadStorePatches[loadStoreAddr[i]] = patch; + } } if (!store) diff --git a/src/NDS.cpp b/src/NDS.cpp index 6981a42..8cd7f93 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -814,6 +814,7 @@ bool DoSavestate(Savestate* file) if (!file->Saving) { ARMJIT::ResetBlockCache(); + ARMJIT_Memory::Reset(); } #endif diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.cpp b/src/frontend/qt_sdl/EmuSettingsDialog.cpp index 9ee7b9a..77301b7 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.cpp +++ b/src/frontend/qt_sdl/EmuSettingsDialog.cpp @@ -34,6 +34,7 @@ EmuSettingsDialog* EmuSettingsDialog::currentDlg = nullptr; extern char* EmuDirectory; extern bool RunningSomething; +bool EmuSettingsDialog::needsReset = false; EmuSettingsDialog::EmuSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::EmuSettingsDialog) { @@ -121,6 +122,8 @@ void EmuSettingsDialog::verifyFirmware() void EmuSettingsDialog::done(int r) { + needsReset = false; + if (r == QDialog::Accepted) { verifyFirmware(); @@ -186,6 +189,8 @@ void EmuSettingsDialog::done(int r) Config::DirectBoot = directBoot; Config::Save(); + + needsReset = true; } } diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.h b/src/frontend/qt_sdl/EmuSettingsDialog.h index 268036c..c24a147 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.h +++ b/src/frontend/qt_sdl/EmuSettingsDialog.h @@ -50,6 +50,8 @@ public: currentDlg = nullptr; } + static bool needsReset; + private slots: void done(int r); diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 4557d0e..de6887c 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -1641,14 +1641,19 @@ void MainWindow::onStop() void MainWindow::onOpenEmuSettings() { + emuThread->emuPause(); + EmuSettingsDialog* dlg = EmuSettingsDialog::openDlg(this); connect(dlg, &EmuSettingsDialog::finished, this, &MainWindow::onEmuSettingsDialogFinished); } void MainWindow::onEmuSettingsDialogFinished(int res) { - if (RunningSomething) + if (EmuSettingsDialog::needsReset) + { + emuThread->emuUnpause(); onReset(); + } } void MainWindow::onOpenInputConfig() |