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:
parent
a3d46e4133
commit
5001f78b1d
24 changed files with 1005 additions and 621 deletions
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue