Support multi-level page tables
This commit is contained in:
parent
4cde30e92a
commit
8e0cd3d2fd
11 changed files with 283 additions and 138 deletions
|
@ -161,7 +161,7 @@ namespace ChocolArm64.Instructions
|
|||
|
||||
EmitReadIntFallback(context, size);
|
||||
|
||||
context.Emit(OpCodes.Br_S, lblEnd);
|
||||
context.Emit(OpCodes.Br, lblEnd);
|
||||
|
||||
context.MarkLabel(lblFastPath);
|
||||
|
||||
|
@ -192,7 +192,7 @@ namespace ChocolArm64.Instructions
|
|||
|
||||
EmitReadVectorFallback(context, size);
|
||||
|
||||
context.Emit(OpCodes.Br_S, lblEnd);
|
||||
context.Emit(OpCodes.Br, lblEnd);
|
||||
|
||||
context.MarkLabel(lblFastPath);
|
||||
|
||||
|
@ -217,7 +217,7 @@ namespace ChocolArm64.Instructions
|
|||
|
||||
EmitWriteIntFallback(context, size);
|
||||
|
||||
context.Emit(OpCodes.Br_S, lblEnd);
|
||||
context.Emit(OpCodes.Br, lblEnd);
|
||||
|
||||
context.MarkLabel(lblFastPath);
|
||||
|
||||
|
@ -255,7 +255,7 @@ namespace ChocolArm64.Instructions
|
|||
|
||||
EmitWriteVectorFallback(context, size);
|
||||
|
||||
context.Emit(OpCodes.Br_S, lblEnd);
|
||||
context.Emit(OpCodes.Br, lblEnd);
|
||||
|
||||
context.MarkLabel(lblFastPath);
|
||||
|
||||
|
@ -283,24 +283,40 @@ namespace ChocolArm64.Instructions
|
|||
|
||||
private static void EmitPtPointerLoad(ILEmitterCtx context, ILLabel lblFallbackPath)
|
||||
{
|
||||
context.EmitLdint(_tempIntAddress);
|
||||
|
||||
context.EmitLsr(MemoryManager.PageBits);
|
||||
|
||||
context.EmitLdc_I(IntPtr.Size);
|
||||
|
||||
context.Emit(OpCodes.Mul);
|
||||
|
||||
if (context.CurrOp.RegisterSize == RegisterSize.Int32)
|
||||
{
|
||||
context.Emit(OpCodes.Conv_U8);
|
||||
}
|
||||
|
||||
context.EmitLdc_I8(context.Memory.PageTable.ToInt64());
|
||||
|
||||
context.Emit(OpCodes.Add);
|
||||
context.Emit(OpCodes.Conv_I);
|
||||
context.Emit(OpCodes.Ldind_I);
|
||||
|
||||
int bit = MemoryManager.PageBits;
|
||||
|
||||
do
|
||||
{
|
||||
context.EmitLdint(_tempIntAddress);
|
||||
|
||||
if (context.CurrOp.RegisterSize == RegisterSize.Int32)
|
||||
{
|
||||
context.Emit(OpCodes.Conv_U8);
|
||||
}
|
||||
|
||||
context.EmitLsr(bit);
|
||||
|
||||
bit += context.Memory.PtLevelBits;
|
||||
|
||||
if (bit < context.Memory.AddressSpaceBits)
|
||||
{
|
||||
context.EmitLdc_I8(context.Memory.PtLevelMask);
|
||||
|
||||
context.Emit(OpCodes.And);
|
||||
}
|
||||
|
||||
context.EmitLdc_I8(IntPtr.Size);
|
||||
|
||||
context.Emit(OpCodes.Mul);
|
||||
context.Emit(OpCodes.Conv_I);
|
||||
context.Emit(OpCodes.Add);
|
||||
context.Emit(OpCodes.Ldind_I);
|
||||
}
|
||||
while (bit < context.Memory.AddressSpaceBits);
|
||||
|
||||
if (!context.Memory.HasWriteWatchSupport)
|
||||
{
|
||||
|
|
|
@ -29,21 +29,46 @@ namespace ChocolArm64.Memory
|
|||
|
||||
internal IntPtr PageTable => _pageTable;
|
||||
|
||||
internal int PtLevelBits { get; }
|
||||
internal int PtLevelSize { get; }
|
||||
internal int PtLevelMask { get; }
|
||||
|
||||
public bool HasWriteWatchSupport => MemoryManagement.HasWriteWatchSupport;
|
||||
|
||||
public int AddressSpaceBits { get; }
|
||||
public long AddressSpaceSize { get; }
|
||||
|
||||
public MemoryManager(IntPtr ram, long addressSpaceSize = 1L << 39)
|
||||
public MemoryManager(
|
||||
IntPtr ram,
|
||||
int addressSpaceBits = 48,
|
||||
bool useFlatPageTable = false)
|
||||
{
|
||||
Ram = ram;
|
||||
|
||||
_ramPtr = (byte*)ram;
|
||||
|
||||
AddressSpaceSize = addressSpaceSize;
|
||||
AddressSpaceBits = addressSpaceBits;
|
||||
AddressSpaceSize = 1L << addressSpaceBits;
|
||||
|
||||
long pageTableSize = (addressSpaceSize / PageSize) * IntPtr.Size;
|
||||
//When flag page table is requested, we use a single
|
||||
//array for the mappings of the entire address space.
|
||||
//This has better performance, but also high RAM usage.
|
||||
//The multi level page table uses 9 bits per level, so
|
||||
//the RAM usage is lower, but the performance is also
|
||||
//lower, because it's needed to do multiple reads per translation.
|
||||
if (useFlatPageTable)
|
||||
{
|
||||
PtLevelBits = addressSpaceBits - PageBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
PtLevelBits = 9;
|
||||
}
|
||||
|
||||
_pageTable = Allocate((ulong)pageTableSize);
|
||||
PtLevelSize = 1 << PtLevelBits;
|
||||
PtLevelMask = PtLevelSize - 1;
|
||||
|
||||
_pageTable = Allocate((ulong)(PtLevelSize * IntPtr.Size));
|
||||
}
|
||||
|
||||
public void Map(long va, long pa, long size)
|
||||
|
@ -75,14 +100,10 @@ namespace ChocolArm64.Memory
|
|||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
byte* ptr = ((byte**)_pageTable)[position >> PageBits];
|
||||
|
||||
IntPtr* pt = (IntPtr*)_pageTable;
|
||||
byte* ptr = GetPtEntry(position);
|
||||
|
||||
ulong ptrUlong = (ulong)ptr;
|
||||
|
||||
long ptrLong = (long)ptr;
|
||||
|
||||
if ((ptrUlong & PteFlagsMask) != 0)
|
||||
{
|
||||
ptrUlong &= ~(ulong)PteFlagsMask;
|
||||
|
@ -100,7 +121,7 @@ namespace ChocolArm64.Memory
|
|||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
byte* ptr = ((byte**)_pageTable)[position >> PageBits];
|
||||
byte* ptr = GetPtEntry(position);
|
||||
|
||||
ulong ptrUlong = (ulong)ptr;
|
||||
|
||||
|
@ -119,6 +140,11 @@ namespace ChocolArm64.Memory
|
|||
return new IntPtr(ptr + (position & PageMask));
|
||||
}
|
||||
|
||||
private byte* GetPtEntry(long position)
|
||||
{
|
||||
return *(byte**)GetPtPtr(position);
|
||||
}
|
||||
|
||||
private void SetPtEntries(long va, byte* ptr, long size)
|
||||
{
|
||||
long endPosition = (va + size + PageMask) & ~PageMask;
|
||||
|
@ -138,12 +164,7 @@ namespace ChocolArm64.Memory
|
|||
|
||||
private void SetPtEntry(long position, byte* ptr)
|
||||
{
|
||||
if (!IsValidPosition(position))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(position));
|
||||
}
|
||||
|
||||
((byte**)_pageTable)[position >> PageBits] = ptr;
|
||||
*(byte**)GetPtPtr(position) = ptr;
|
||||
}
|
||||
|
||||
private void SetPtEntryFlag(long position, long flag)
|
||||
|
@ -162,13 +183,22 @@ namespace ChocolArm64.Memory
|
|||
|
||||
while (true)
|
||||
{
|
||||
IntPtr old = pt[position >> PageBits];
|
||||
IntPtr* ptPtr = GetPtPtr(position);
|
||||
|
||||
IntPtr modified = setFlag
|
||||
? new IntPtr(old.ToInt64() | flag)
|
||||
: new IntPtr(old.ToInt64() & ~flag);
|
||||
IntPtr old = *ptPtr;
|
||||
|
||||
IntPtr origValue = Interlocked.CompareExchange(ref pt[position >> PageBits], modified, old);
|
||||
long modified = old.ToInt64();
|
||||
|
||||
if (setFlag)
|
||||
{
|
||||
modified |= flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
modified &= ~flag;
|
||||
}
|
||||
|
||||
IntPtr origValue = Interlocked.CompareExchange(ref *ptPtr, new IntPtr(modified), old);
|
||||
|
||||
if (origValue == old)
|
||||
{
|
||||
|
@ -177,6 +207,57 @@ namespace ChocolArm64.Memory
|
|||
}
|
||||
}
|
||||
|
||||
private IntPtr* GetPtPtr(long position)
|
||||
{
|
||||
if (!IsValidPosition(position))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(position));
|
||||
}
|
||||
|
||||
IntPtr nextPtr = _pageTable;
|
||||
|
||||
IntPtr* ptePtr = null;
|
||||
|
||||
int bit = PageBits;
|
||||
|
||||
while (true)
|
||||
{
|
||||
long index = (position >> bit) & PtLevelMask;
|
||||
|
||||
ptePtr = &((IntPtr*)nextPtr)[index];
|
||||
|
||||
bit += PtLevelBits;
|
||||
|
||||
if (bit >= AddressSpaceBits)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
nextPtr = *ptePtr;
|
||||
|
||||
if (nextPtr == IntPtr.Zero)
|
||||
{
|
||||
//Entry does not yet exist, allocate a new one.
|
||||
IntPtr newPtr = Allocate((ulong)(PtLevelSize * IntPtr.Size));
|
||||
|
||||
//Try to swap the current pointer (should be zero), with the allocated one.
|
||||
nextPtr = Interlocked.Exchange(ref *ptePtr, newPtr);
|
||||
|
||||
//If the old pointer is not null, then another thread already has set it.
|
||||
if (nextPtr != IntPtr.Zero)
|
||||
{
|
||||
Free(newPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextPtr = newPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ptePtr;
|
||||
}
|
||||
|
||||
public bool IsRegionModified(long position, long size)
|
||||
{
|
||||
if (!HasWriteWatchSupport)
|
||||
|
@ -318,7 +399,7 @@ namespace ChocolArm64.Memory
|
|||
|
||||
public bool IsValidPosition(long position)
|
||||
{
|
||||
return (ulong)position <= (ulong)AddressSpaceSize;
|
||||
return (ulong)position < (ulong)AddressSpaceSize;
|
||||
}
|
||||
|
||||
internal bool AtomicCompareExchange2xInt32(
|
||||
|
@ -899,8 +980,32 @@ namespace ChocolArm64.Memory
|
|||
|
||||
if (ptr != IntPtr.Zero)
|
||||
{
|
||||
Free(ptr);
|
||||
FreePageTableEntry(ptr, PageBits);
|
||||
}
|
||||
}
|
||||
|
||||
private void FreePageTableEntry(IntPtr ptr, int levelBitEnd)
|
||||
{
|
||||
levelBitEnd += PtLevelBits;
|
||||
|
||||
if (levelBitEnd >= AddressSpaceBits)
|
||||
{
|
||||
Free(ptr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (int index = 0; index < PtLevelSize; index++)
|
||||
{
|
||||
IntPtr ptePtr = ((IntPtr*)ptr)[index];
|
||||
|
||||
if (ptePtr != IntPtr.Zero)
|
||||
{
|
||||
FreePageTableEntry(ptePtr, levelBitEnd);
|
||||
}
|
||||
}
|
||||
|
||||
Free(ptr);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
using ChocolArm64.Memory;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.HLE
|
||||
{
|
||||
|
|
|
@ -80,12 +80,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
public bool IsPaused { get; private set; }
|
||||
|
||||
public Translator Translator { get; private set; }
|
||||
|
||||
public MemoryManager CpuMemory { get; private set; }
|
||||
|
||||
public Translator Translator { get; private set; }
|
||||
|
||||
private SvcHandler _svcHandler;
|
||||
|
||||
private Horizon _system;
|
||||
|
||||
public HleProcessDebugger Debugger { get; private set; }
|
||||
|
||||
public KProcess(Horizon system) : base(system)
|
||||
|
@ -93,12 +95,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
_processLock = new object();
|
||||
_threadingLock = new object();
|
||||
|
||||
CpuMemory = new MemoryManager(system.Device.Memory.RamPointer);
|
||||
_system = system;
|
||||
|
||||
AddressArbiter = new KAddressArbiter(system);
|
||||
|
||||
MemoryManager = new KMemoryManager(system, CpuMemory);
|
||||
|
||||
_fullTlsPages = new SortedDictionary<ulong, KTlsPageInfo>();
|
||||
_freeTlsPages = new SortedDictionary<ulong, KTlsPageInfo>();
|
||||
|
||||
|
@ -108,10 +108,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
_threads = new LinkedList<KThread>();
|
||||
|
||||
Translator = new Translator(CpuMemory);
|
||||
|
||||
Translator.CpuTrace += CpuTraceHandler;
|
||||
|
||||
_svcHandler = new SvcHandler(system.Device, this);
|
||||
|
||||
Debugger = new HleProcessDebugger(this);
|
||||
|
@ -129,6 +125,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
AddressSpaceType addrSpaceType = (AddressSpaceType)((creationInfo.MmuFlags >> 1) & 7);
|
||||
|
||||
InitializeMemoryManager(addrSpaceType, memRegion);
|
||||
|
||||
bool aslrEnabled = ((creationInfo.MmuFlags >> 5) & 1) != 0;
|
||||
|
||||
ulong codeAddress = creationInfo.CodeAddress;
|
||||
|
@ -236,6 +234,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
|
||||
AddressSpaceType addrSpaceType = (AddressSpaceType)((creationInfo.MmuFlags >> 1) & 7);
|
||||
|
||||
InitializeMemoryManager(addrSpaceType, memRegion);
|
||||
|
||||
bool aslrEnabled = ((creationInfo.MmuFlags >> 5) & 1) != 0;
|
||||
|
||||
ulong codeAddress = creationInfo.CodeAddress;
|
||||
|
@ -403,7 +403,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
case AddressSpaceType.Addr36Bits:
|
||||
case AddressSpaceType.Addr39Bits:
|
||||
_memoryUsageCapacity = MemoryManager.HeapRegionEnd -
|
||||
MemoryManager.HeapRegionStart;
|
||||
MemoryManager.HeapRegionStart;
|
||||
break;
|
||||
|
||||
case AddressSpaceType.Addr32BitsNoMap:
|
||||
|
@ -1008,6 +1008,31 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
|||
}
|
||||
}
|
||||
|
||||
private void InitializeMemoryManager(AddressSpaceType addrSpaceType, MemoryRegion memRegion)
|
||||
{
|
||||
int addrSpaceBits;
|
||||
|
||||
switch (addrSpaceType)
|
||||
{
|
||||
case AddressSpaceType.Addr32Bits: addrSpaceBits = 32; break;
|
||||
case AddressSpaceType.Addr36Bits: addrSpaceBits = 36; break;
|
||||
case AddressSpaceType.Addr32BitsNoMap: addrSpaceBits = 32; break;
|
||||
case AddressSpaceType.Addr39Bits: addrSpaceBits = 39; break;
|
||||
|
||||
default: throw new ArgumentException(nameof(addrSpaceType));
|
||||
}
|
||||
|
||||
bool useFlatPageTable = memRegion == MemoryRegion.Application;
|
||||
|
||||
CpuMemory = new MemoryManager(_system.Device.Memory.RamPointer, addrSpaceBits, useFlatPageTable);
|
||||
|
||||
MemoryManager = new KMemoryManager(_system, CpuMemory);
|
||||
|
||||
Translator = new Translator(CpuMemory);
|
||||
|
||||
Translator.CpuTrace += CpuTraceHandler;
|
||||
}
|
||||
|
||||
public void PrintCurrentThreadStackTrace()
|
||||
{
|
||||
System.Scheduler.GetCurrentThread().PrintGuestStackTrace();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -152,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);
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace Ryujinx.Tests.Cpu
|
|||
_entryPoint = Position;
|
||||
|
||||
_ramPointer = Marshal.AllocHGlobal(new IntPtr(_size));
|
||||
_memory = new MemoryManager(_ramPointer, 1L << 32);
|
||||
_memory = new MemoryManager(_ramPointer);
|
||||
_memory.Map(Position, 0, _size);
|
||||
|
||||
Translator translator = new Translator(_memory);
|
||||
|
|
Loading…
Add table
Reference in a new issue