Optimize address translation and write tracking on the MMU (#571)

* Implement faster address translation and write tracking on the MMU

* Rename MemoryAlloc to MemoryManagement, and other nits

* Support multi-level page tables

* Fix typo

* Reword comment a bit

* Support scalar vector loads/stores on the memory fast path, and minor fixes

* Add missing cast

* Alignment

* Fix VirtualFree function signature

* Change MemoryProtection enum to uint aswell for consistency
This commit is contained in:
gdkchan 2019-02-24 04:24:35 -03:00 committed by jduncanator
parent a3d46e4133
commit 5001f78b1d
24 changed files with 1005 additions and 621 deletions

View file

@ -1,5 +1,4 @@
using ChocolArm64.Events;
using ChocolArm64.Memory;
using ChocolArm64.State;
using Ryujinx.HLE.HOS.Kernel.Process;
using System;
@ -11,14 +10,12 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
private Switch _device;
private KProcess _process;
private Horizon _system;
private MemoryManager _memory;
public SvcHandler(Switch device, KProcess process)
{
_device = device;
_process = process;
_system = device.System;
_memory = process.CpuMemory;
}
public void SvcCall(object sender, InstExceptionEventArgs e)

View file

@ -93,7 +93,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
private KernelResult SendSyncRequest(ulong messagePtr, ulong size, int handle)
{
byte[] messageData = _memory.ReadBytes((long)messagePtr, (long)size);
byte[] messageData = _process.CpuMemory.ReadBytes((long)messagePtr, (long)size);
KClientSession clientSession = _process.HandleTable.GetObject<KClientSession>(handle);
@ -142,7 +142,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
ipcMessage.Thread.ObjSyncResult = IpcHandler.IpcCall(
_device,
_process,
_memory,
_process.CpuMemory,
ipcMessage.Session,
ipcMessage.Message,
ipcMessage.MessagePtr);

View file

@ -62,11 +62,6 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
attributeMask,
attributeValue);
if (result == KernelResult.Success)
{
_memory.StopObservingRegion((long)position, (long)size);
}
return result;
}
@ -157,14 +152,14 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
{
KMemoryInfo blkInfo = _process.MemoryManager.QueryMemory(position);
_memory.WriteUInt64((long)infoPtr + 0x00, blkInfo.Address);
_memory.WriteUInt64((long)infoPtr + 0x08, blkInfo.Size);
_memory.WriteInt32 ((long)infoPtr + 0x10, (int)blkInfo.State & 0xff);
_memory.WriteInt32 ((long)infoPtr + 0x14, (int)blkInfo.Attribute);
_memory.WriteInt32 ((long)infoPtr + 0x18, (int)blkInfo.Permission);
_memory.WriteInt32 ((long)infoPtr + 0x1c, blkInfo.IpcRefCount);
_memory.WriteInt32 ((long)infoPtr + 0x20, blkInfo.DeviceRefCount);
_memory.WriteInt32 ((long)infoPtr + 0x24, 0);
_process.CpuMemory.WriteUInt64((long)infoPtr + 0x00, blkInfo.Address);
_process.CpuMemory.WriteUInt64((long)infoPtr + 0x08, blkInfo.Size);
_process.CpuMemory.WriteInt32 ((long)infoPtr + 0x10, (int)blkInfo.State & 0xff);
_process.CpuMemory.WriteInt32 ((long)infoPtr + 0x14, (int)blkInfo.Attribute);
_process.CpuMemory.WriteInt32 ((long)infoPtr + 0x18, (int)blkInfo.Permission);
_process.CpuMemory.WriteInt32 ((long)infoPtr + 0x1c, blkInfo.IpcRefCount);
_process.CpuMemory.WriteInt32 ((long)infoPtr + 0x20, blkInfo.DeviceRefCount);
_process.CpuMemory.WriteInt32 ((long)infoPtr + 0x24, 0);
return KernelResult.Success;
}

View file

@ -201,7 +201,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
private void OutputDebugString(ulong strPtr, ulong size)
{
string str = MemoryHelper.ReadAsciiString(_memory, (long)strPtr, (long)size);
string str = MemoryHelper.ReadAsciiString(_process.CpuMemory, (long)strPtr, (long)size);
Logger.PrintWarning(LogClass.KernelSvc, str);
}

View file

@ -1,3 +1,4 @@
using ChocolArm64.Memory;
using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Process;
using Ryujinx.HLE.HOS.Kernel.Threading;
@ -346,79 +347,81 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return KernelResult.InvalidThread;
}
_memory.WriteUInt64((long)address + 0x0, thread.Context.ThreadState.X0);
_memory.WriteUInt64((long)address + 0x8, thread.Context.ThreadState.X1);
_memory.WriteUInt64((long)address + 0x10, thread.Context.ThreadState.X2);
_memory.WriteUInt64((long)address + 0x18, thread.Context.ThreadState.X3);
_memory.WriteUInt64((long)address + 0x20, thread.Context.ThreadState.X4);
_memory.WriteUInt64((long)address + 0x28, thread.Context.ThreadState.X5);
_memory.WriteUInt64((long)address + 0x30, thread.Context.ThreadState.X6);
_memory.WriteUInt64((long)address + 0x38, thread.Context.ThreadState.X7);
_memory.WriteUInt64((long)address + 0x40, thread.Context.ThreadState.X8);
_memory.WriteUInt64((long)address + 0x48, thread.Context.ThreadState.X9);
_memory.WriteUInt64((long)address + 0x50, thread.Context.ThreadState.X10);
_memory.WriteUInt64((long)address + 0x58, thread.Context.ThreadState.X11);
_memory.WriteUInt64((long)address + 0x60, thread.Context.ThreadState.X12);
_memory.WriteUInt64((long)address + 0x68, thread.Context.ThreadState.X13);
_memory.WriteUInt64((long)address + 0x70, thread.Context.ThreadState.X14);
_memory.WriteUInt64((long)address + 0x78, thread.Context.ThreadState.X15);
_memory.WriteUInt64((long)address + 0x80, thread.Context.ThreadState.X16);
_memory.WriteUInt64((long)address + 0x88, thread.Context.ThreadState.X17);
_memory.WriteUInt64((long)address + 0x90, thread.Context.ThreadState.X18);
_memory.WriteUInt64((long)address + 0x98, thread.Context.ThreadState.X19);
_memory.WriteUInt64((long)address + 0xa0, thread.Context.ThreadState.X20);
_memory.WriteUInt64((long)address + 0xa8, thread.Context.ThreadState.X21);
_memory.WriteUInt64((long)address + 0xb0, thread.Context.ThreadState.X22);
_memory.WriteUInt64((long)address + 0xb8, thread.Context.ThreadState.X23);
_memory.WriteUInt64((long)address + 0xc0, thread.Context.ThreadState.X24);
_memory.WriteUInt64((long)address + 0xc8, thread.Context.ThreadState.X25);
_memory.WriteUInt64((long)address + 0xd0, thread.Context.ThreadState.X26);
_memory.WriteUInt64((long)address + 0xd8, thread.Context.ThreadState.X27);
_memory.WriteUInt64((long)address + 0xe0, thread.Context.ThreadState.X28);
_memory.WriteUInt64((long)address + 0xe8, thread.Context.ThreadState.X29);
_memory.WriteUInt64((long)address + 0xf0, thread.Context.ThreadState.X30);
_memory.WriteUInt64((long)address + 0xf8, thread.Context.ThreadState.X31);
MemoryManager memory = currentProcess.CpuMemory;
_memory.WriteInt64((long)address + 0x100, thread.LastPc);
memory.WriteUInt64((long)address + 0x0, thread.Context.ThreadState.X0);
memory.WriteUInt64((long)address + 0x8, thread.Context.ThreadState.X1);
memory.WriteUInt64((long)address + 0x10, thread.Context.ThreadState.X2);
memory.WriteUInt64((long)address + 0x18, thread.Context.ThreadState.X3);
memory.WriteUInt64((long)address + 0x20, thread.Context.ThreadState.X4);
memory.WriteUInt64((long)address + 0x28, thread.Context.ThreadState.X5);
memory.WriteUInt64((long)address + 0x30, thread.Context.ThreadState.X6);
memory.WriteUInt64((long)address + 0x38, thread.Context.ThreadState.X7);
memory.WriteUInt64((long)address + 0x40, thread.Context.ThreadState.X8);
memory.WriteUInt64((long)address + 0x48, thread.Context.ThreadState.X9);
memory.WriteUInt64((long)address + 0x50, thread.Context.ThreadState.X10);
memory.WriteUInt64((long)address + 0x58, thread.Context.ThreadState.X11);
memory.WriteUInt64((long)address + 0x60, thread.Context.ThreadState.X12);
memory.WriteUInt64((long)address + 0x68, thread.Context.ThreadState.X13);
memory.WriteUInt64((long)address + 0x70, thread.Context.ThreadState.X14);
memory.WriteUInt64((long)address + 0x78, thread.Context.ThreadState.X15);
memory.WriteUInt64((long)address + 0x80, thread.Context.ThreadState.X16);
memory.WriteUInt64((long)address + 0x88, thread.Context.ThreadState.X17);
memory.WriteUInt64((long)address + 0x90, thread.Context.ThreadState.X18);
memory.WriteUInt64((long)address + 0x98, thread.Context.ThreadState.X19);
memory.WriteUInt64((long)address + 0xa0, thread.Context.ThreadState.X20);
memory.WriteUInt64((long)address + 0xa8, thread.Context.ThreadState.X21);
memory.WriteUInt64((long)address + 0xb0, thread.Context.ThreadState.X22);
memory.WriteUInt64((long)address + 0xb8, thread.Context.ThreadState.X23);
memory.WriteUInt64((long)address + 0xc0, thread.Context.ThreadState.X24);
memory.WriteUInt64((long)address + 0xc8, thread.Context.ThreadState.X25);
memory.WriteUInt64((long)address + 0xd0, thread.Context.ThreadState.X26);
memory.WriteUInt64((long)address + 0xd8, thread.Context.ThreadState.X27);
memory.WriteUInt64((long)address + 0xe0, thread.Context.ThreadState.X28);
memory.WriteUInt64((long)address + 0xe8, thread.Context.ThreadState.X29);
memory.WriteUInt64((long)address + 0xf0, thread.Context.ThreadState.X30);
memory.WriteUInt64((long)address + 0xf8, thread.Context.ThreadState.X31);
_memory.WriteUInt64((long)address + 0x108, (ulong)thread.Context.ThreadState.Psr);
memory.WriteInt64((long)address + 0x100, thread.LastPc);
_memory.WriteVector128((long)address + 0x110, thread.Context.ThreadState.V0);
_memory.WriteVector128((long)address + 0x120, thread.Context.ThreadState.V1);
_memory.WriteVector128((long)address + 0x130, thread.Context.ThreadState.V2);
_memory.WriteVector128((long)address + 0x140, thread.Context.ThreadState.V3);
_memory.WriteVector128((long)address + 0x150, thread.Context.ThreadState.V4);
_memory.WriteVector128((long)address + 0x160, thread.Context.ThreadState.V5);
_memory.WriteVector128((long)address + 0x170, thread.Context.ThreadState.V6);
_memory.WriteVector128((long)address + 0x180, thread.Context.ThreadState.V7);
_memory.WriteVector128((long)address + 0x190, thread.Context.ThreadState.V8);
_memory.WriteVector128((long)address + 0x1a0, thread.Context.ThreadState.V9);
_memory.WriteVector128((long)address + 0x1b0, thread.Context.ThreadState.V10);
_memory.WriteVector128((long)address + 0x1c0, thread.Context.ThreadState.V11);
_memory.WriteVector128((long)address + 0x1d0, thread.Context.ThreadState.V12);
_memory.WriteVector128((long)address + 0x1e0, thread.Context.ThreadState.V13);
_memory.WriteVector128((long)address + 0x1f0, thread.Context.ThreadState.V14);
_memory.WriteVector128((long)address + 0x200, thread.Context.ThreadState.V15);
_memory.WriteVector128((long)address + 0x210, thread.Context.ThreadState.V16);
_memory.WriteVector128((long)address + 0x220, thread.Context.ThreadState.V17);
_memory.WriteVector128((long)address + 0x230, thread.Context.ThreadState.V18);
_memory.WriteVector128((long)address + 0x240, thread.Context.ThreadState.V19);
_memory.WriteVector128((long)address + 0x250, thread.Context.ThreadState.V20);
_memory.WriteVector128((long)address + 0x260, thread.Context.ThreadState.V21);
_memory.WriteVector128((long)address + 0x270, thread.Context.ThreadState.V22);
_memory.WriteVector128((long)address + 0x280, thread.Context.ThreadState.V23);
_memory.WriteVector128((long)address + 0x290, thread.Context.ThreadState.V24);
_memory.WriteVector128((long)address + 0x2a0, thread.Context.ThreadState.V25);
_memory.WriteVector128((long)address + 0x2b0, thread.Context.ThreadState.V26);
_memory.WriteVector128((long)address + 0x2c0, thread.Context.ThreadState.V27);
_memory.WriteVector128((long)address + 0x2d0, thread.Context.ThreadState.V28);
_memory.WriteVector128((long)address + 0x2e0, thread.Context.ThreadState.V29);
_memory.WriteVector128((long)address + 0x2f0, thread.Context.ThreadState.V30);
_memory.WriteVector128((long)address + 0x300, thread.Context.ThreadState.V31);
memory.WriteUInt64((long)address + 0x108, (ulong)thread.Context.ThreadState.Psr);
_memory.WriteInt32((long)address + 0x310, thread.Context.ThreadState.Fpcr);
_memory.WriteInt32((long)address + 0x314, thread.Context.ThreadState.Fpsr);
_memory.WriteInt64((long)address + 0x318, thread.Context.ThreadState.Tpidr);
memory.WriteVector128((long)address + 0x110, thread.Context.ThreadState.V0);
memory.WriteVector128((long)address + 0x120, thread.Context.ThreadState.V1);
memory.WriteVector128((long)address + 0x130, thread.Context.ThreadState.V2);
memory.WriteVector128((long)address + 0x140, thread.Context.ThreadState.V3);
memory.WriteVector128((long)address + 0x150, thread.Context.ThreadState.V4);
memory.WriteVector128((long)address + 0x160, thread.Context.ThreadState.V5);
memory.WriteVector128((long)address + 0x170, thread.Context.ThreadState.V6);
memory.WriteVector128((long)address + 0x180, thread.Context.ThreadState.V7);
memory.WriteVector128((long)address + 0x190, thread.Context.ThreadState.V8);
memory.WriteVector128((long)address + 0x1a0, thread.Context.ThreadState.V9);
memory.WriteVector128((long)address + 0x1b0, thread.Context.ThreadState.V10);
memory.WriteVector128((long)address + 0x1c0, thread.Context.ThreadState.V11);
memory.WriteVector128((long)address + 0x1d0, thread.Context.ThreadState.V12);
memory.WriteVector128((long)address + 0x1e0, thread.Context.ThreadState.V13);
memory.WriteVector128((long)address + 0x1f0, thread.Context.ThreadState.V14);
memory.WriteVector128((long)address + 0x200, thread.Context.ThreadState.V15);
memory.WriteVector128((long)address + 0x210, thread.Context.ThreadState.V16);
memory.WriteVector128((long)address + 0x220, thread.Context.ThreadState.V17);
memory.WriteVector128((long)address + 0x230, thread.Context.ThreadState.V18);
memory.WriteVector128((long)address + 0x240, thread.Context.ThreadState.V19);
memory.WriteVector128((long)address + 0x250, thread.Context.ThreadState.V20);
memory.WriteVector128((long)address + 0x260, thread.Context.ThreadState.V21);
memory.WriteVector128((long)address + 0x270, thread.Context.ThreadState.V22);
memory.WriteVector128((long)address + 0x280, thread.Context.ThreadState.V23);
memory.WriteVector128((long)address + 0x290, thread.Context.ThreadState.V24);
memory.WriteVector128((long)address + 0x2a0, thread.Context.ThreadState.V25);
memory.WriteVector128((long)address + 0x2b0, thread.Context.ThreadState.V26);
memory.WriteVector128((long)address + 0x2c0, thread.Context.ThreadState.V27);
memory.WriteVector128((long)address + 0x2d0, thread.Context.ThreadState.V28);
memory.WriteVector128((long)address + 0x2e0, thread.Context.ThreadState.V29);
memory.WriteVector128((long)address + 0x2f0, thread.Context.ThreadState.V30);
memory.WriteVector128((long)address + 0x300, thread.Context.ThreadState.V31);
memory.WriteInt32((long)address + 0x310, thread.Context.ThreadState.Fpcr);
memory.WriteInt32((long)address + 0x314, thread.Context.ThreadState.Fpsr);
memory.WriteInt64((long)address + 0x318, thread.Context.ThreadState.Tpidr);
return KernelResult.Success;
}

View file

@ -25,7 +25,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
for (int index = 0; index < handlesCount; index++)
{
int handle = _memory.ReadInt32((long)handlesPtr + index * 4);
int handle = _process.CpuMemory.ReadInt32((long)handlesPtr + index * 4);
KSynchronizationObject syncObj = _process.HandleTable.GetObject<KSynchronizationObject>(handle);