aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRSDuck <RSDuck@users.noreply.github.com>2020-07-04 18:58:00 +0200
committerRSDuck <RSDuck@users.noreply.github.com>2020-07-04 18:58:00 +0200
commit778623a8b7ded3a66fc838840ce85626f5feed05 (patch)
tree1fc317f4aa173cc9933c74163756103c2e67e0bb
parent62c6e2f703d88660e0ca9bda78032c5bd6b63a78 (diff)
make linux work and fix a few bugs
-rw-r--r--src/ARMJIT.cpp8
-rw-r--r--src/ARMJIT_Memory.cpp121
-rw-r--r--src/ARMJIT_x64/ARMJIT_LoadStore.cpp22
-rw-r--r--src/NDS.cpp1
-rw-r--r--src/frontend/qt_sdl/EmuSettingsDialog.cpp5
-rw-r--r--src/frontend/qt_sdl/EmuSettingsDialog.h2
-rw-r--r--src/frontend/qt_sdl/main.cpp7
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()