From 18ac1c4045cc156068bd5a4fa82035c79c74e25d Mon Sep 17 00:00:00 2001 From: gdkchan Date: Wed, 7 Feb 2018 13:44:48 -0300 Subject: [PATCH] Removed parts of the MMU functionality to use memory directly (faster, but potentially more dangerous, WIP), also changed the Shl/Sshr immediate instructions to use IL instead of calling the method --- GLScreen.cs | 16 ++++- Ryujinx/Cpu/Instruction/AInstEmitSimd.cs | 71 +++++++++++++----- Ryujinx/Cpu/Instruction/ASoftFallback.cs | 52 -------------- Ryujinx/Cpu/Memory/AMemory.cs | 79 +++------------------ Ryujinx/Cpu/Memory/AMemoryMgr.cs | 38 +--------- Ryujinx/OsHle/Handles/HSharedMem.cs | 1 + Ryujinx/OsHle/Handles/HTransferMem.cs | 4 +- Ryujinx/OsHle/Horizon.cs | 7 ++ Ryujinx/OsHle/Objects/ViIHOSBinderDriver.cs | 3 +- Ryujinx/OsHle/Svc/SvcMemory.cs | 6 +- 10 files changed, 89 insertions(+), 188 deletions(-) diff --git a/GLScreen.cs b/GLScreen.cs index d757db8fc..3e16f7f1d 100644 --- a/GLScreen.cs +++ b/GLScreen.cs @@ -6,6 +6,7 @@ using Gal; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; +using Ryujinx.OsHle; using System; namespace Ryujinx @@ -60,12 +61,14 @@ namespace Ryujinx unsafe void UploadBitmap() { - if (Renderer.FrameBufferPtr == 0) + int FbSize = Width * Height * 4; + + if (Renderer.FrameBufferPtr == 0 || Renderer.FrameBufferPtr + FbSize > uint.MaxValue) { return; } - byte* SrcPtr = (byte*)IntPtr.Add(Ns.Ram, (int)Renderer.FrameBufferPtr); + byte* SrcPtr = (byte*)Ns.Ram + (uint)Renderer.FrameBufferPtr; for (int Y = 0; Y < Height; Y++) { @@ -275,7 +278,14 @@ void main(void) { { unsafe { - byte* Ptr = (byte*)IntPtr.Add(Ns.Ram, (int)Ns.Os.HidOffset); + long HidOffset = Ns.Os.GetVirtHidOffset(); + + if (HidOffset == 0 || HidOffset + Horizon.HidSize > uint.MaxValue) + { + return; + } + + byte* Ptr = (byte*)Ns.Ram + (uint)HidOffset; int State = 0; diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs index c41703bfb..ccf0e3577 100644 --- a/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs +++ b/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs @@ -361,15 +361,7 @@ namespace ChocolArm64.Instruction { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; - Context.EmitLdvec(Op.Rn); - Context.EmitLdc_I4(Op.Imm - (8 << Op.Size)); - Context.EmitLdc_I4(Op.Size); - - ASoftFallback.EmitCall(Context, - nameof(ASoftFallback.Shl64), - nameof(ASoftFallback.Shl128)); - - Context.EmitStvec(Op.Rd); + EmitVectorImmBinaryZx(Context, OpCodes.Shl, Op.Imm - (8 << Op.Size)); } public static void Smax_V(AILEmitterCtx Context) => EmitVectorSmax(Context); @@ -396,15 +388,7 @@ namespace ChocolArm64.Instruction { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; - Context.EmitLdvec(Op.Rn); - Context.EmitLdc_I4((8 << (Op.Size + 1)) - Op.Imm); - Context.EmitLdc_I4(Op.Size); - - ASoftFallback.EmitCall(Context, - nameof(ASoftFallback.Sshr64), - nameof(ASoftFallback.Sshr128)); - - Context.EmitStvec(Op.Rd); + EmitVectorImmBinarySx(Context, OpCodes.Shr, (8 << (Op.Size + 1)) - Op.Imm); } public static void St__V(AILEmitterCtx Context) => EmitSimdMultLdSt(Context, IsLoad: false); @@ -881,6 +865,55 @@ namespace ChocolArm64.Instruction } } + private static void EmitVectorImmBinarySx(AILEmitterCtx Context, OpCode ILOp, long Imm) + { + EmitVectorImmBinarySx(Context, () => Context.Emit(ILOp), Imm); + } + + private static void EmitVectorImmBinaryZx(AILEmitterCtx Context, OpCode ILOp, long Imm) + { + EmitVectorImmBinaryZx(Context, () => Context.Emit(ILOp), Imm); + } + + private static void EmitVectorImmBinarySx(AILEmitterCtx Context, Action Emit, long Imm) + { + EmitVectorImmBinaryOp(Context, Emit, Imm, true); + } + + private static void EmitVectorImmBinaryZx(AILEmitterCtx Context, Action Emit, long Imm) + { + EmitVectorImmBinaryOp(Context, Emit, Imm, false); + } + + private static void EmitVectorImmBinaryOp(AILEmitterCtx Context, Action Emit, long Imm, bool Signed) + { + AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; + + int Bytes = Context.CurrOp.GetBitsCount() >> 3; + + for (int Index = 0; Index < (Bytes >> Op.Size); Index++) + { + Context.EmitLdvec(Op.Rd); + Context.EmitLdc_I4(Index); + Context.EmitLdc_I4(Op.Size); + + EmitVectorExtract(Context, Op.Rn, Index, Signed); + + Context.EmitLdc_I8(Imm); + + Emit(); + + ASoftFallback.EmitCall(Context, nameof(ASoftFallback.InsertVec)); + + Context.EmitStvec(Op.Rd); + } + + if (Op.RegisterSize == ARegisterSize.SIMD64) + { + EmitVectorZeroUpper(Context, Op.Rd); + } + } + private static void EmitVectorCmp(AILEmitterCtx Context, OpCode ILOp) { AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; @@ -936,7 +969,7 @@ namespace ChocolArm64.Instruction private static void EmitVectorExtract(AILEmitterCtx Context, int Reg, int Index, bool Signed) { - AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; + IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp; Context.EmitLdvec(Reg); Context.EmitLdc_I4(Index); diff --git a/Ryujinx/Cpu/Instruction/ASoftFallback.cs b/Ryujinx/Cpu/Instruction/ASoftFallback.cs index 910123148..0d5271320 100644 --- a/Ryujinx/Cpu/Instruction/ASoftFallback.cs +++ b/Ryujinx/Cpu/Instruction/ASoftFallback.cs @@ -790,32 +790,6 @@ namespace ChocolArm64.Instruction return Res; } - public static AVec Shl64(AVec Vector, int Shift, int Size) - { - return Shl(Vector, Shift, Size, 8); - } - - public static AVec Shl128(AVec Vector, int Shift, int Size) - { - return Shl(Vector, Shift, Size, 16); - } - - private static AVec Shl(AVec Vector, int Shift, int Size, int Bytes) - { - AVec Res = new AVec(); - - int Elems = Bytes >> Size; - - for (int Index = 0; Index < Elems; Index++) - { - ulong Value = ExtractVec(Vector, Index, Size); - - Res = InsertVec(Res, Index, Size, Value << Shift); - } - - return Res; - } - public static AVec Sshll(AVec Vector, int Shift, int Size) { return Sshll_(Vector, Shift, Size, false); @@ -843,32 +817,6 @@ namespace ChocolArm64.Instruction return Res; } - public static AVec Sshr64(AVec Vector, int Shift, int Size) - { - return Sshr(Vector, Shift, Size, 8); - } - - public static AVec Sshr128(AVec Vector, int Shift, int Size) - { - return Sshr(Vector, Shift, Size, 16); - } - - private static AVec Sshr(AVec Vector, int Shift, int Size, int Bytes) - { - AVec Res = new AVec(); - - int Elems = Bytes >> Size; - - for (int Index = 0; Index < Elems; Index++) - { - long Value = ExtractSVec(Vector, Index, Size); - - Res = InsertSVec(Res, Index, Size, Value >> Shift); - } - - return Res; - } - public static AVec Tbl1_V64(AVec Vector, AVec Tb0) { return Tbl(Vector, 8, Tb0); diff --git a/Ryujinx/Cpu/Memory/AMemory.cs b/Ryujinx/Cpu/Memory/AMemory.cs index af1c75bf0..8159b341e 100644 --- a/Ryujinx/Cpu/Memory/AMemory.cs +++ b/Ryujinx/Cpu/Memory/AMemory.cs @@ -119,55 +119,22 @@ namespace ChocolArm64.Memory public byte ReadByte(long Position) { - return *((byte*)(RamPtr + Manager.GetPhys(Position, AMemoryPerm.Read))); + return *((byte*)(RamPtr + (uint)Position)); } public ushort ReadUInt16(long Position) { - long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Read); - - if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 2)) - { - return *((ushort*)(RamPtr + PhysPos)); - } - else - { - return (ushort)( - ReadByte(Position + 0) << 0 | - ReadByte(Position + 1) << 8); - } + return *((ushort*)(RamPtr + (uint)Position)); } public uint ReadUInt32(long Position) { - long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Read); - - if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 4)) - { - return *((uint*)(RamPtr + PhysPos)); - } - else - { - return (uint)( - ReadUInt16(Position + 0) << 0 | - ReadUInt16(Position + 2) << 16); - } + return *((uint*)(RamPtr + (uint)Position)); } public ulong ReadUInt64(long Position) { - long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Read); - - if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 8)) - { - return *((ulong*)(RamPtr + PhysPos)); - } - else - { - return - (ulong)ReadUInt32(Position + 0) << 0 | - (ulong)ReadUInt32(Position + 4) << 32; - } + return *((ulong*)(RamPtr + (uint)Position)); } public AVec ReadVector128(long Position) @@ -186,52 +153,22 @@ namespace ChocolArm64.Memory public void WriteByte(long Position, byte Value) { - *((byte*)(RamPtr + Manager.GetPhys(Position, AMemoryPerm.Write))) = Value; + *((byte*)(RamPtr + (uint)Position)) = Value; } public void WriteUInt16(long Position, ushort Value) { - long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Write); - - if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 2)) - { - *((ushort*)(RamPtr + PhysPos)) = Value; - } - else - { - WriteByte(Position + 0, (byte)(Value >> 0)); - WriteByte(Position + 1, (byte)(Value >> 8)); - } + *((ushort*)(RamPtr + (uint)Position)) = Value; } public void WriteUInt32(long Position, uint Value) { - long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Write); - - if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 4)) - { - *((uint*)(RamPtr + PhysPos)) = Value; - } - else - { - WriteUInt16(Position + 0, (ushort)(Value >> 0)); - WriteUInt16(Position + 2, (ushort)(Value >> 16)); - } + *((uint*)(RamPtr + (uint)Position)) = Value; } public void WriteUInt64(long Position, ulong Value) { - long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Write); - - if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 8)) - { - *((ulong*)(RamPtr + PhysPos)) = Value; - } - else - { - WriteUInt32(Position + 0, (uint)(Value >> 0)); - WriteUInt32(Position + 4, (uint)(Value >> 32)); - } + *((ulong*)(RamPtr + (uint)Position)) = Value; } public void WriteVector128(long Position, AVec Value) diff --git a/Ryujinx/Cpu/Memory/AMemoryMgr.cs b/Ryujinx/Cpu/Memory/AMemoryMgr.cs index 4d995469f..0c2c5a50b 100644 --- a/Ryujinx/Cpu/Memory/AMemoryMgr.cs +++ b/Ryujinx/Cpu/Memory/AMemoryMgr.cs @@ -6,8 +6,8 @@ namespace ChocolArm64.Memory { public class AMemoryMgr { - public const long AddrSize = 1L << 36; - public const long RamSize = 2L * 1024 * 1024 * 1024; + public const long AddrSize = RamSize; + public const long RamSize = 4L * 1024 * 1024 * 1024; private const int PTLvl0Bits = 11; private const int PTLvl1Bits = 13; @@ -117,7 +117,7 @@ namespace ChocolArm64.Memory while ((ulong)Size < (ulong)HeapSize) { - Allocator.Free(GetPhys(Position, AMemoryPerm.None)); + Allocator.Free(Position); Position += PageSize; } @@ -254,38 +254,6 @@ namespace ChocolArm64.Memory return new AMemoryMapInfo(Start, Size, BaseEntry.Type, BaseEntry.Perm); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public long GetPhys(long Position, AMemoryPerm Perm) - { - if (!HasPTEntry(Position)) - { - if (Position < 0x08000000) - { - Console.WriteLine($"HACK: Ignoring bad access at {Position:x16}"); - - return 0; - } - - throw new VmmPageFaultException(Position); - } - - PTEntry Entry = GetPTEntry(Position); - - long AbsPos = Entry.Position + (Position & PageMask); - - if (Entry.Map == PTMap.Mirror) - { - return GetPhys(AbsPos, Perm); - } - - if (Entry.Map == PTMap.Unmapped) - { - throw new VmmPageFaultException(Position); - } - - return AbsPos; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool HasPTEntry(long Position) { diff --git a/Ryujinx/OsHle/Handles/HSharedMem.cs b/Ryujinx/OsHle/Handles/HSharedMem.cs index acc1e7ebd..2030ff0a4 100644 --- a/Ryujinx/OsHle/Handles/HSharedMem.cs +++ b/Ryujinx/OsHle/Handles/HSharedMem.cs @@ -3,6 +3,7 @@ namespace Ryujinx.OsHle.Handles class HSharedMem { public long PhysPos { get; private set; } + public long VirtPos { get; set; } public HSharedMem(long PhysPos) { diff --git a/Ryujinx/OsHle/Handles/HTransferMem.cs b/Ryujinx/OsHle/Handles/HTransferMem.cs index 962d1b664..b24e14129 100644 --- a/Ryujinx/OsHle/Handles/HTransferMem.cs +++ b/Ryujinx/OsHle/Handles/HTransferMem.cs @@ -9,15 +9,13 @@ namespace Ryujinx.OsHle.Handles public long Position { get; private set; } public long Size { get; private set; } - public long PhysPos { get; private set; } - public HTransferMem(AMemory Memory, AMemoryPerm Perm, long Position, long Size, long PhysPos) + public HTransferMem(AMemory Memory, AMemoryPerm Perm, long Position, long Size) { this.Memory = Memory; this.Perm = Perm; this.Position = Position; this.Size = Size; - this.PhysPos = PhysPos; } } } \ No newline at end of file diff --git a/Ryujinx/OsHle/Horizon.cs b/Ryujinx/OsHle/Horizon.cs index bae33f8eb..04744bdfa 100644 --- a/Ryujinx/OsHle/Horizon.cs +++ b/Ryujinx/OsHle/Horizon.cs @@ -159,5 +159,12 @@ namespace Ryujinx.OsHle Handles.Delete(Handle); } + + public long GetVirtHidOffset() + { + HSharedMem HidSharedMem = Handles.GetData(HidHandle); + + return HidSharedMem.VirtPos; + } } } \ No newline at end of file diff --git a/Ryujinx/OsHle/Objects/ViIHOSBinderDriver.cs b/Ryujinx/OsHle/Objects/ViIHOSBinderDriver.cs index 72a472ae5..13393eafc 100644 --- a/Ryujinx/OsHle/Objects/ViIHOSBinderDriver.cs +++ b/Ryujinx/OsHle/Objects/ViIHOSBinderDriver.cs @@ -155,8 +155,7 @@ namespace Ryujinx.OsHle.Objects HNvMap NvMap = Context.Ns.Os.Handles.GetData(Handle); - Context.Ns.Gpu.Renderer.FrameBufferPtr = - Context.Memory.Manager.GetPhys(NvMap.Address, AMemoryPerm.Read); + Context.Ns.Gpu.Renderer.FrameBufferPtr = NvMap.Address; } return MakeReplyParcel(Context, 0); diff --git a/Ryujinx/OsHle/Svc/SvcMemory.cs b/Ryujinx/OsHle/Svc/SvcMemory.cs index c1249b403..70988eb0b 100644 --- a/Ryujinx/OsHle/Svc/SvcMemory.cs +++ b/Ryujinx/OsHle/Svc/SvcMemory.cs @@ -77,6 +77,8 @@ namespace Ryujinx.OsHle.Svc long Src = Position; long Dst = HndData.PhysPos; + HndData.VirtPos = Src; + if (Memory.Manager.MapPhys(Src, Dst, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm)) { @@ -113,9 +115,7 @@ namespace Ryujinx.OsHle.Svc Memory.Manager.Reprotect(Position, Size, (AMemoryPerm)Perm); - long PhysPos = Memory.Manager.GetPhys(Position, AMemoryPerm.None); - - HTransferMem HndData = new HTransferMem(Memory, MapInfo.Perm, Position, Size, PhysPos); + HTransferMem HndData = new HTransferMem(Memory, MapInfo.Perm, Position, Size); int Handle = Ns.Os.Handles.GenerateId(HndData);