From b8fd849247854a61d005e4b65a09bc279fc7dcf7 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Thu, 8 Mar 2018 16:27:16 -0300 Subject: [PATCH] Enable full memory checking on all memory accesses --- ChocolArm64/Memory/AMemory.cs | 246 ++++++++++++------ ChocolArm64/Memory/AMemoryMgr.cs | 186 +++++++++++-- ChocolArm64/Memory/AMemoryPerm.cs | 2 +- Ryujinx.Core/Hid/Hid.cs | 200 +++++--------- Ryujinx.Core/Loaders/Executable.cs | 30 +-- .../Loaders/Executables/IExecutable.cs | 8 +- Ryujinx.Core/Loaders/Executables/Nro.cs | 18 +- Ryujinx.Core/Loaders/Executables/Nso.cs | 29 +-- Ryujinx.Core/OsHle/Handles/HSharedMem.cs | 37 +-- Ryujinx.Core/OsHle/Homebrew.cs | 2 +- Ryujinx.Core/OsHle/Horizon.cs | 4 +- Ryujinx.Core/OsHle/Ipc/IpcMessage.cs | 14 +- Ryujinx.Core/OsHle/MemoryRegions.cs | 11 +- Ryujinx.Core/OsHle/Process.cs | 15 +- .../OsHle/Services/Nv/ServiceNvDrv.cs | 42 +-- Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs | 2 +- Ryujinx.Core/OsHle/Svc/SvcMemory.cs | 12 +- Ryujinx.Core/PerformanceStatistics.cs | 5 +- Ryujinx.Core/Switch.cs | 8 +- Ryujinx.Tests/Cpu/CpuTest.cs | 8 +- 20 files changed, 499 insertions(+), 380 deletions(-) diff --git a/ChocolArm64/Memory/AMemory.cs b/ChocolArm64/Memory/AMemory.cs index 0d202fed30..0aed73a32f 100644 --- a/ChocolArm64/Memory/AMemory.cs +++ b/ChocolArm64/Memory/AMemory.cs @@ -41,9 +41,9 @@ namespace ChocolArm64.Memory private byte* RamPtr; - public AMemory(IntPtr Ram) + public AMemory(IntPtr Ram, long RamSize, int AddressSpaceBits) { - Manager = new AMemoryMgr(); + Manager = new AMemoryMgr(RamSize, AddressSpaceBits); Monitors = new Dictionary(); @@ -142,90 +142,121 @@ namespace ChocolArm64.Memory [MethodImpl(MethodImplOptions.AggressiveInlining)] public byte ReadByte(long Position) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Read); -#endif + byte* Ptr = RamPtr + Position; - return *((byte*)(RamPtr + (uint)Position)); + if (Manager.IsDirectRead(Position)) + { + return *Ptr; + } + + return ReadByteSlow(Position); + } + + private byte ReadByteSlow(long Position) + { + EnsureAccessIsValid(Position, AMemoryPerm.Read); + + long PA = Manager.TranslatePosition(Position); + + return *(RamPtr + PA); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ushort ReadUInt16(long Position) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Read); -#endif + ushort* Ptr = (ushort*)(RamPtr + Position); - return *((ushort*)(RamPtr + (uint)Position)); + if (Manager.IsDirectRead(Position)) + { + return *Ptr; + } + + throw new VmmPageFaultException(Position); + } + + private ushort ReadUInt16Slow(long Position) + { + EnsureAccessIsValid(Position, AMemoryPerm.Read); + EnsureAccessIsValid(Position + 1, AMemoryPerm.Read); + + long PA = Manager.TranslatePosition(Position); + + return *((ushort*)(RamPtr + PA)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public uint ReadUInt32(long Position) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Read); -#endif + uint* Ptr = (uint*)(RamPtr + Position); - return *((uint*)(RamPtr + (uint)Position)); + if (Manager.IsDirectRead(Position)) + { + return *Ptr; + } + + return ReadUInt32Slow(Position); + } + + private uint ReadUInt32Slow(long Position) + { + EnsureAccessIsValid(Position, AMemoryPerm.Read); + EnsureAccessIsValid(Position + 3, AMemoryPerm.Read); + + long PA = Manager.TranslatePosition(Position); + + return *((uint*)(RamPtr + PA)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ulong ReadUInt64(long Position) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Read); -#endif + ulong* Ptr = (ulong*)(RamPtr + Position); - return *((ulong*)(RamPtr + (uint)Position)); + if (Manager.IsDirectRead(Position)) + { + return *Ptr; + } + + return ReadUInt64Slow(Position); + } + + private ulong ReadUInt64Slow(long Position) + { + EnsureAccessIsValid(Position, AMemoryPerm.Read); + EnsureAccessIsValid(Position + 7, AMemoryPerm.Read); + + long PA = Manager.TranslatePosition(Position); + + return *((ulong*)(RamPtr + PA)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public AVec ReadVector8(long Position) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Read); -#endif - return new AVec() { B0 = ReadByte(Position) }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public AVec ReadVector16(long Position) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Read); -#endif - return new AVec() { H0 = ReadUInt16(Position) }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public AVec ReadVector32(long Position) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Read); -#endif - return new AVec() { W0 = ReadUInt32(Position) }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public AVec ReadVector64(long Position) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Read); -#endif - return new AVec() { X0 = ReadUInt64(Position) }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public AVec ReadVector128(long Position) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Read); -#endif - return new AVec() { X0 = ReadUInt64(Position + 0), @@ -241,94 +272,161 @@ namespace ChocolArm64.Memory [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteByte(long Position, byte Value) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Write); -#endif + byte* Ptr = RamPtr + Position; - *((byte*)(RamPtr + (uint)Position)) = Value; + if (Manager.IsDirectWrite(Position)) + { + *Ptr = Value; + + return; + } + + WriteByteSlow(Position, Value); + } + + private void WriteByteSlow(long Position, byte Value) + { + EnsureAccessIsValid(Position, AMemoryPerm.Write); + + long PA = Manager.TranslatePosition(Position); + + *(RamPtr + PA) = Value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteUInt16(long Position, ushort Value) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Write); -#endif + ushort* Ptr = (ushort*)(RamPtr + Position); - *((ushort*)(RamPtr + (uint)Position)) = Value; + if (Manager.IsDirectWrite(Position)) + { + *Ptr = Value; + + return; + } + + WriteUInt16Slow(Position, Value); + } + + private void WriteUInt16Slow(long Position, ushort Value) + { + EnsureAccessIsValid(Position, AMemoryPerm.Write); + EnsureAccessIsValid(Position + 1, AMemoryPerm.Write); + + long PA = Manager.TranslatePosition(Position); + + *((ushort*)(RamPtr + PA)) = Value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteUInt32(long Position, uint Value) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Write); -#endif + uint* Ptr = (uint*)(RamPtr + Position); - *((uint*)(RamPtr + (uint)Position)) = Value; + if (Manager.IsDirectWrite(Position)) + { + *Ptr = Value; + + return; + } + + WriteUInt32Slow(Position, Value); + } + + private void WriteUInt32Slow(long Position, uint Value) + { + EnsureAccessIsValid(Position, AMemoryPerm.Write); + EnsureAccessIsValid(Position + 3, AMemoryPerm.Write); + + long PA = Manager.TranslatePosition(Position); + + *((uint*)(RamPtr + PA)) = Value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteUInt64(long Position, ulong Value) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Write); -#endif + ulong* Ptr = (ulong*)(RamPtr + Position); - *((ulong*)(RamPtr + (uint)Position)) = Value; + if (Manager.IsDirectWrite(Position)) + { + *Ptr = Value; + + return; + } + + WriteUInt64Slow(Position, Value); + } + + private void WriteUInt64Slow(long Position, ulong Value) + { + EnsureAccessIsValid(Position, AMemoryPerm.Write); + EnsureAccessIsValid(Position + 7, AMemoryPerm.Write); + + long PA = Manager.TranslatePosition(Position); + + *((ulong*)(RamPtr + PA)) = Value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteVector8(long Position, AVec Value) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Write); -#endif - WriteByte(Position, Value.B0); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteVector16(long Position, AVec Value) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Write); -#endif - WriteUInt16(Position, Value.H0); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteVector32(long Position, AVec Value) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Write); -#endif - WriteUInt32(Position, Value.W0); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteVector64(long Position, AVec Value) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Write); -#endif - WriteUInt64(Position, Value.X0); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteVector128(long Position, AVec Value) { -#if DEBUG - EnsureAccessIsValid(Position, AMemoryPerm.Write); -#endif - WriteUInt64(Position + 0, Value.X0); WriteUInt64(Position + 8, Value.X1); } + public void WriteDirectUnchecked(long Position, byte[] Data) + { + byte* Ptr = (byte*)(RamPtr + Position); + + int Pages = (Data.Length + AMemoryMgr.PageMask) / AMemoryMgr.PageSize; + + int RemSize = Data.Length; + + for (int Page = 0; Page < Pages; Page++) + { + int Offset = Page * AMemoryMgr.PageSize; + + if (!Manager.IsMapped(Position + Offset)) + { + throw new VmmPageFaultException(Position + Offset); + } + + int ToCopy = Math.Min(AMemoryMgr.PageSize, RemSize); + + for (; Offset < Page * AMemoryMgr.PageSize + ToCopy; Offset++) + { + *Ptr++ = Data[Offset]; + } + + RemSize -= AMemoryMgr.PageSize; + } + } + private void EnsureAccessIsValid(long Position, AMemoryPerm Perm) { if (!Manager.IsMapped(Position)) diff --git a/ChocolArm64/Memory/AMemoryMgr.cs b/ChocolArm64/Memory/AMemoryMgr.cs index bc36445242..1c28aea1bc 100644 --- a/ChocolArm64/Memory/AMemoryMgr.cs +++ b/ChocolArm64/Memory/AMemoryMgr.cs @@ -4,28 +4,41 @@ namespace ChocolArm64.Memory { public class AMemoryMgr { - public const long AddrSize = RamSize; - public const long RamSize = 4L * 1024 * 1024 * 1024; + private ulong RamSize; + + private ulong AddressSpaceSize; + + private int PTLvl0Bits; + private int PTLvl1Bits; + + private int PTLvl0Size; + private int PTLvl1Size; + + private int PTLvl0Mask; + private int PTLvl1Mask; + + private int PTLvl0Bit; - private const int PTLvl0Bits = 10; - private const int PTLvl1Bits = 10; private const int PTPageBits = 12; - private const int PTLvl0Size = 1 << PTLvl0Bits; - private const int PTLvl1Size = 1 << PTLvl1Bits; - public const int PageSize = 1 << PTPageBits; + public const int PageSize = 1 << PTPageBits; - private const int PTLvl0Mask = PTLvl0Size - 1; - private const int PTLvl1Mask = PTLvl1Size - 1; - public const int PageMask = PageSize - 1; + public const int PageMask = PageSize - 1; - private const int PTLvl0Bit = PTPageBits + PTLvl1Bits; - private const int PTLvl1Bit = PTPageBits; + private const int PTLvl1Bit = PTPageBits; - private enum PTMap + private enum PTMap : byte { - Unmapped, - Mapped + Unmapped = 0, + Mapped = 1, + + Direct = 1 << 5, + DirectRead = Direct | 1 << 6, + DirectWrite = Direct | 1 << 7, + + DirectRW = + DirectRead | + DirectWrite } private struct PTEntry @@ -33,38 +46,121 @@ namespace ChocolArm64.Memory public PTMap Map; public AMemoryPerm Perm; + public long Position; public int Type; public int Attr; - public PTEntry(PTMap Map, AMemoryPerm Perm, int Type, int Attr) + public PTEntry(PTMap Map, long Position, AMemoryPerm Perm, int Type, int Attr) { this.Map = Map; + this.Position = Position; this.Perm = Perm; this.Type = Type; this.Attr = Attr; } } + private PTMap[] MapTypes; + private PTEntry[][] PageTable; - public AMemoryMgr() + public AMemoryMgr(long RamSize, int AddressSpaceBits) { + this.RamSize = (ulong)RamSize; + + AddressSpaceSize = 1UL << AddressSpaceBits; + + int RemBits = AddressSpaceBits - PTPageBits; + + PTLvl0Bits = RemBits >> 1; + PTLvl1Bits = RemBits - PTLvl0Bits; + + PTLvl0Size = 1 << PTLvl0Bits; + PTLvl1Size = 1 << PTLvl1Bits; + + PTLvl0Mask = PTLvl0Size - 1; + PTLvl1Mask = PTLvl1Size - 1; + + PTLvl0Bit = PTPageBits + PTLvl1Bits; + + MapTypes = new PTMap[1 << RemBits]; + PageTable = new PTEntry[PTLvl0Size][]; } - public void Map(long Position, long Size, int Type, AMemoryPerm Perm) + public void MapDirectRX(long Position, long Size, int Type) { - SetPTEntry(Position, Size, new PTEntry(PTMap.Mapped, Perm, Type, 0)); + if ((ulong)Position >= RamSize) + { + throw new ArgumentOutOfRangeException(nameof(Position)); + } + + if ((ulong)(Position + Size) > RamSize) + { + throw new ArgumentOutOfRangeException(nameof(Size)); + } + + SetPTEntry(Position, Size, new PTEntry(PTMap.DirectRead, 0, AMemoryPerm.RX, Type, 0)); + } + + public void MapDirectRO(long Position, long Size, int Type) + { + if ((ulong)Position >= RamSize) + { + throw new ArgumentOutOfRangeException(nameof(Position)); + } + + if ((ulong)(Position + Size) > RamSize) + { + throw new ArgumentOutOfRangeException(nameof(Size)); + } + + SetPTEntry(Position, Size, new PTEntry(PTMap.DirectRead, 0, AMemoryPerm.Read, Type, 0)); + } + + public void MapDirectRW(long Position, long Size, int Type) + { + if ((ulong)Position >= RamSize) + { + throw new ArgumentOutOfRangeException(nameof(Position)); + } + + if ((ulong)(Position + Size) > RamSize) + { + throw new ArgumentOutOfRangeException(nameof(Size)); + } + + SetPTEntry(Position, Size, new PTEntry(PTMap.DirectRW, 0, AMemoryPerm.RW, Type, 0)); + } + + public void Map(long VA, long PA, long Size, int Type, AMemoryPerm Perm) + { + if ((ulong)VA >= AddressSpaceSize) + { + throw new ArgumentOutOfRangeException(nameof(VA)); + } + + if ((ulong)PA >= RamSize) + { + throw new ArgumentOutOfRangeException(nameof(PA)); + } + + if ((ulong)(PA + Size) > RamSize || (ulong)(VA + Size) > AddressSpaceSize) + { + throw new ArgumentOutOfRangeException(nameof(Size)); + } + + SetPTEntry(VA, Size, new PTEntry(PTMap.Mapped, PA, Perm, Type, 0)); } public void Unmap(long Position, long Size) { - SetPTEntry(Position, Size, new PTEntry(PTMap.Unmapped, 0, 0, 0)); + SetPTEntry(Position, Size, new PTEntry(PTMap.Unmapped, 0, 0, 0, 0)); } public void Unmap(long Position, long Size, int Type) { - SetPTEntry(Position, Size, Type, new PTEntry(PTMap.Unmapped, 0, 0, 0)); + SetPTEntry(Position, Size, Type, new PTEntry(PTMap.Unmapped, 0, 0, 0, 0)); } public void Reprotect(long Position, long Size, AMemoryPerm Perm) @@ -121,7 +217,7 @@ namespace ChocolArm64.Memory Start -= PageSize; } - while (End < AddrSize && IsSameSegment(End)) + while ((ulong)End < AddressSpaceSize && IsSameSegment(End)) { End += PageSize; } @@ -199,6 +295,35 @@ namespace ChocolArm64.Memory return PageTable[L0][L1].Map != PTMap.Unmapped; } + public long TranslatePosition(long Position) + { + if (IsDirect(Position)) + { + return Position; + } + else + { + long BasePosition = GetPTEntry(Position).Position; + + return BasePosition + (Position & AMemoryMgr.PageMask); + } + } + + public bool IsDirect(long Position) + { + return (MapTypes[(ulong)Position >> PTPageBits] & PTMap.Direct) != 0; + } + + public bool IsDirectRead(long Position) + { + return (MapTypes[(ulong)Position >> PTPageBits] & PTMap.DirectRead) != 0; + } + + public bool IsDirectWrite(long Position) + { + return (MapTypes[(ulong)Position >> PTPageBits] & PTMap.DirectWrite) != 0; + } + private PTEntry GetPTEntry(long Position) { long L0 = (Position >> PTLvl0Bit) & PTLvl0Mask; @@ -214,10 +339,14 @@ namespace ChocolArm64.Memory private void SetPTEntry(long Position, long Size, PTEntry Entry) { + Entry.Position &= ~PageMask; + while (Size > 0) { SetPTEntry(Position, Entry); + Entry.Position += PageSize; + Position += PageSize; Size -= PageSize; } @@ -225,12 +354,13 @@ namespace ChocolArm64.Memory private void SetPTEntry(long Position, long Size, int Type, PTEntry Entry) { - while (Size > 0) + Entry.Position &= ~PageMask; + + while (Size > 0 && GetPTEntry(Position).Type == Type) { - if (GetPTEntry(Position).Type == Type) - { - SetPTEntry(Position, Entry); - } + SetPTEntry(Position, Entry); + + Entry.Position += PageSize; Position += PageSize; Size -= PageSize; @@ -253,6 +383,8 @@ namespace ChocolArm64.Memory } PageTable[L0][L1] = Entry; + + MapTypes[Position >> PTPageBits] = Entry.Map; } } } \ No newline at end of file diff --git a/ChocolArm64/Memory/AMemoryPerm.cs b/ChocolArm64/Memory/AMemoryPerm.cs index b425eb94b2..50d4057cbf 100644 --- a/ChocolArm64/Memory/AMemoryPerm.cs +++ b/ChocolArm64/Memory/AMemoryPerm.cs @@ -3,7 +3,7 @@ using System; namespace ChocolArm64.Memory { [Flags] - public enum AMemoryPerm + public enum AMemoryPerm : byte { None = 0, Read = 1 << 0, diff --git a/Ryujinx.Core/Hid/Hid.cs b/Ryujinx.Core/Hid/Hid.cs index 249747c152..027cf44f18 100644 --- a/Ryujinx.Core/Hid/Hid.cs +++ b/Ryujinx.Core/Hid/Hid.cs @@ -1,6 +1,4 @@ -using ChocolArm64.Memory; -using Ryujinx.Core.OsHle.Handles; -using System; +using System; using System.Diagnostics; namespace Ryujinx.Core.Input @@ -62,51 +60,16 @@ namespace Ryujinx.Core.Input private const int HidEntryCount = 17; - private object ShMemLock; - - private long[] ShMemPositions; - private IntPtr Ram; - public Hid(IntPtr Ram) + public long PA { get; private set; } + + public Hid(IntPtr Ram, long PA) { this.Ram = Ram; + this.PA = PA; - ShMemLock = new object(); - - ShMemPositions = new long[0]; - } - - internal void ShMemMap(object sender, EventArgs e) - { - HSharedMem SharedMem = (HSharedMem)sender; - - lock (ShMemLock) - { - ShMemPositions = SharedMem.GetVirtualPositions(); - - long BasePosition = ShMemPositions[ShMemPositions.Length - 1]; - - Logging.Info($"HID shared memory successfully mapped to 0x{BasePosition:x16}!"); - - Init(BasePosition); - } - } - - internal void ShMemUnmap(object sender, EventArgs e) - { - HSharedMem SharedMem = (HSharedMem)sender; - - lock (ShMemLock) - { - ShMemPositions = SharedMem.GetVirtualPositions(); - } - } - - private void Init(long BasePosition) - { InitializeJoyconPair( - BasePosition, JoyConColor.Body_Neon_Red, JoyConColor.Buttons_Neon_Red, JoyConColor.Body_Neon_Blue, @@ -114,13 +77,12 @@ namespace Ryujinx.Core.Input } private void InitializeJoyconPair( - long BasePosition, JoyConColor LeftColorBody, JoyConColor LeftColorButtons, JoyConColor RightColorBody, JoyConColor RightColorButtons) { - long BaseControllerOffset = BasePosition + HidControllersOffset + 8 * HidControllerSize; + long BaseControllerOffset = HidControllersOffset + 8 * HidControllerSize; HidControllerType Type = HidControllerType.ControllerType_Handheld | @@ -159,123 +121,105 @@ namespace Ryujinx.Core.Input HidJoystickPosition LeftStick, HidJoystickPosition RightStick) { - lock (ShMemLock) - { - foreach (long Position in ShMemPositions) - { - long ControllerOffset = Position + HidControllersOffset; + long ControllerOffset = HidControllersOffset; - ControllerOffset += (int)ControllerId * HidControllerSize; + ControllerOffset += (int)ControllerId * HidControllerSize; - ControllerOffset += HidControllerHeaderSize; + ControllerOffset += HidControllerHeaderSize; - ControllerOffset += (int)ControllerLayout * HidControllerLayoutsSize; + ControllerOffset += (int)ControllerLayout * HidControllerLayoutsSize; - long LastEntry = ReadInt64(ControllerOffset + 0x10); + long LastEntry = ReadInt64(ControllerOffset + 0x10); - long CurrEntry = (LastEntry + 1) % HidEntryCount; + long CurrEntry = (LastEntry + 1) % HidEntryCount; - long Timestamp = Stopwatch.GetTimestamp(); + long Timestamp = Stopwatch.GetTimestamp(); - WriteInt64(ControllerOffset + 0x0, Timestamp); - WriteInt64(ControllerOffset + 0x8, HidEntryCount); - WriteInt64(ControllerOffset + 0x10, CurrEntry); - WriteInt64(ControllerOffset + 0x18, HidEntryCount - 1); + WriteInt64(ControllerOffset + 0x0, Timestamp); + WriteInt64(ControllerOffset + 0x8, HidEntryCount); + WriteInt64(ControllerOffset + 0x10, CurrEntry); + WriteInt64(ControllerOffset + 0x18, HidEntryCount - 1); - ControllerOffset += HidControllersLayoutHeaderSize; + ControllerOffset += HidControllersLayoutHeaderSize; - ControllerOffset += CurrEntry * HidControllersInputEntrySize; + ControllerOffset += CurrEntry * HidControllersInputEntrySize; - WriteInt64(ControllerOffset + 0x0, Timestamp); - WriteInt64(ControllerOffset + 0x8, Timestamp); + WriteInt64(ControllerOffset + 0x0, Timestamp); + WriteInt64(ControllerOffset + 0x8, Timestamp); - WriteInt64(ControllerOffset + 0x10, (uint)Buttons); + WriteInt64(ControllerOffset + 0x10, (uint)Buttons); - WriteInt32(ControllerOffset + 0x18, LeftStick.DX); - WriteInt32(ControllerOffset + 0x1c, LeftStick.DY); + WriteInt32(ControllerOffset + 0x18, LeftStick.DX); + WriteInt32(ControllerOffset + 0x1c, LeftStick.DY); - WriteInt64(ControllerOffset + 0x20, RightStick.DX); - WriteInt64(ControllerOffset + 0x24, RightStick.DY); + WriteInt64(ControllerOffset + 0x20, RightStick.DX); + WriteInt64(ControllerOffset + 0x24, RightStick.DY); - WriteInt64(ControllerOffset + 0x28, - (uint)HidControllerConnState.Controller_State_Connected | - (uint)HidControllerConnState.Controller_State_Wired); - } - } + WriteInt64(ControllerOffset + 0x28, + (uint)HidControllerConnState.Controller_State_Connected | + (uint)HidControllerConnState.Controller_State_Wired); } public void SetTouchPoints(params HidTouchPoint[] Points) { - lock (ShMemLock) + long TouchScreenOffset = HidTouchScreenOffset; + + long LastEntry = ReadInt64(TouchScreenOffset + 0x10); + + long CurrEntry = (LastEntry + 1) % HidEntryCount; + + long Timestamp = ReadInt64(TouchScreenOffset) + 1; + + WriteInt64(TouchScreenOffset + 0x0, Timestamp); + WriteInt64(TouchScreenOffset + 0x8, HidEntryCount); + WriteInt64(TouchScreenOffset + 0x10, CurrEntry); + WriteInt64(TouchScreenOffset + 0x18, HidEntryCount - 1); + WriteInt64(TouchScreenOffset + 0x20, Timestamp); + + long TouchEntryOffset = TouchScreenOffset + HidTouchHeaderSize; + + long LastEntryOffset = TouchEntryOffset + LastEntry * HidTouchEntrySize; + + TouchEntryOffset += CurrEntry * HidTouchEntrySize; + + WriteInt64(TouchEntryOffset + 0x0, Timestamp); + WriteInt64(TouchEntryOffset + 0x8, Points.Length); + + TouchEntryOffset += HidTouchEntryHeaderSize; + + const int Padding = 0; + + int Index = 0; + + foreach (HidTouchPoint Point in Points) { - foreach (long Position in ShMemPositions) - { - long TouchScreenOffset = Position + HidTouchScreenOffset; + WriteInt64(TouchEntryOffset + 0x0, Timestamp); + WriteInt32(TouchEntryOffset + 0x8, Padding); + WriteInt32(TouchEntryOffset + 0xc, Index++); + WriteInt32(TouchEntryOffset + 0x10, Point.X); + WriteInt32(TouchEntryOffset + 0x14, Point.Y); + WriteInt32(TouchEntryOffset + 0x18, Point.DiameterX); + WriteInt32(TouchEntryOffset + 0x1c, Point.DiameterY); + WriteInt32(TouchEntryOffset + 0x20, Point.Angle); + WriteInt32(TouchEntryOffset + 0x24, Padding); - long LastEntry = ReadInt64(TouchScreenOffset + 0x10); - - long CurrEntry = (LastEntry + 1) % HidEntryCount; - - long Timestamp = ReadInt64(TouchScreenOffset) + 1; - - WriteInt64(TouchScreenOffset + 0x0, Timestamp); - WriteInt64(TouchScreenOffset + 0x8, HidEntryCount); - WriteInt64(TouchScreenOffset + 0x10, CurrEntry); - WriteInt64(TouchScreenOffset + 0x18, HidEntryCount - 1); - WriteInt64(TouchScreenOffset + 0x20, Timestamp); - - long TouchEntryOffset = TouchScreenOffset + HidTouchHeaderSize; - - long LastEntryOffset = TouchEntryOffset + LastEntry * HidTouchEntrySize; - - TouchEntryOffset += CurrEntry * HidTouchEntrySize; - - WriteInt64(TouchEntryOffset + 0x0, Timestamp); - WriteInt64(TouchEntryOffset + 0x8, Points.Length); - - TouchEntryOffset += HidTouchEntryHeaderSize; - - const int Padding = 0; - - int Index = 0; - - foreach (HidTouchPoint Point in Points) - { - WriteInt64(TouchEntryOffset + 0x0, Timestamp); - WriteInt32(TouchEntryOffset + 0x8, Padding); - WriteInt32(TouchEntryOffset + 0xc, Index++); - WriteInt32(TouchEntryOffset + 0x10, Point.X); - WriteInt32(TouchEntryOffset + 0x14, Point.Y); - WriteInt32(TouchEntryOffset + 0x18, Point.DiameterX); - WriteInt32(TouchEntryOffset + 0x1c, Point.DiameterY); - WriteInt32(TouchEntryOffset + 0x20, Point.Angle); - WriteInt32(TouchEntryOffset + 0x24, Padding); - - TouchEntryOffset += HidTouchEntryTouchSize; - } - } + TouchEntryOffset += HidTouchEntryTouchSize; } } private unsafe long ReadInt64(long Position) { - if ((ulong)Position + 8 > AMemoryMgr.AddrSize) return 0; - - return *((long*)((byte*)Ram + Position)); + return *((long*)((byte*)Ram + PA + Position)); } private unsafe void WriteInt32(long Position, int Value) { - if ((ulong)Position + 4 > AMemoryMgr.AddrSize) return; - - *((int*)((byte*)Ram + Position)) = Value; + *((int*)((byte*)Ram + PA + Position)) = Value; } private unsafe void WriteInt64(long Position, long Value) { - if ((ulong)Position + 8 > AMemoryMgr.AddrSize) return; - - *((long*)((byte*)Ram + Position)) = Value; + *((long*)((byte*)Ram + PA + Position)) = Value; } } } \ No newline at end of file diff --git a/Ryujinx.Core/Loaders/Executable.cs b/Ryujinx.Core/Loaders/Executable.cs index fa204460f6..64bf240642 100644 --- a/Ryujinx.Core/Loaders/Executable.cs +++ b/Ryujinx.Core/Loaders/Executable.cs @@ -28,13 +28,17 @@ namespace Ryujinx.Core.Loaders this.ImageBase = ImageBase; this.ImageEnd = ImageBase; - WriteData(ImageBase + Exe.TextOffset, Exe.Text, MemoryType.CodeStatic, AMemoryPerm.RX); - WriteData(ImageBase + Exe.ROOffset, Exe.RO, MemoryType.Normal, AMemoryPerm.Read); - WriteData(ImageBase + Exe.DataOffset, Exe.Data, MemoryType.Normal, AMemoryPerm.RW); + Memory.Manager.MapDirectRX(ImageBase + Exe.TextOffset, Exe.Text.Length, (int)MemoryType.CodeStatic); + Memory.Manager.MapDirectRO(ImageBase + Exe.ROOffset, Exe.RO.Length, (int)MemoryType.Normal); + Memory.Manager.MapDirectRW(ImageBase + Exe.DataOffset, Exe.Data.Length, (int)MemoryType.Normal); + + Memory.WriteDirectUnchecked(ImageBase + Exe.TextOffset, Exe.Text); + Memory.WriteDirectUnchecked(ImageBase + Exe.ROOffset, Exe.RO); + Memory.WriteDirectUnchecked(ImageBase + Exe.DataOffset, Exe.Data); if (Exe.Mod0Offset == 0) { - int BssOffset = Exe.DataOffset + Exe.Data.Count; + int BssOffset = Exe.DataOffset + Exe.Data.Length; int BssSize = Exe.BssSize; MapBss(ImageBase + BssOffset, BssSize); @@ -90,25 +94,9 @@ namespace Ryujinx.Core.Loaders } } - private void WriteData( - long Position, - IList Data, - MemoryType Type, - AMemoryPerm Perm) - { - Memory.Manager.Map(Position, Data.Count, (int)Type, AMemoryPerm.Write); - - for (int Index = 0; Index < Data.Count; Index++) - { - Memory.WriteByte(Position + Index, Data[Index]); - } - - Memory.Manager.Reprotect(Position, Data.Count, Perm); - } - private void MapBss(long Position, long Size) { - Memory.Manager.Map(Position, Size, (int)MemoryType.Normal, AMemoryPerm.RW); + Memory.Manager.MapDirectRW(Position, Size, (int)MemoryType.Normal); } private ElfRel GetRelocation(long Position) diff --git a/Ryujinx.Core/Loaders/Executables/IExecutable.cs b/Ryujinx.Core/Loaders/Executables/IExecutable.cs index 73787b1d24..09d0aab236 100644 --- a/Ryujinx.Core/Loaders/Executables/IExecutable.cs +++ b/Ryujinx.Core/Loaders/Executables/IExecutable.cs @@ -1,12 +1,10 @@ -using System.Collections.ObjectModel; - namespace Ryujinx.Core.Loaders.Executables { public interface IExecutable { - ReadOnlyCollection Text { get; } - ReadOnlyCollection RO { get; } - ReadOnlyCollection Data { get; } + byte[] Text { get; } + byte[] RO { get; } + byte[] Data { get; } int Mod0Offset { get; } int TextOffset { get; } diff --git a/Ryujinx.Core/Loaders/Executables/Nro.cs b/Ryujinx.Core/Loaders/Executables/Nro.cs index 3cbc4c5d49..9f4ef59f57 100644 --- a/Ryujinx.Core/Loaders/Executables/Nro.cs +++ b/Ryujinx.Core/Loaders/Executables/Nro.cs @@ -1,18 +1,12 @@ -using System; -using System.Collections.ObjectModel; using System.IO; namespace Ryujinx.Core.Loaders.Executables { class Nro : IExecutable { - private byte[] m_Text; - private byte[] m_RO; - private byte[] m_Data; - - public ReadOnlyCollection Text => Array.AsReadOnly(m_Text); - public ReadOnlyCollection RO => Array.AsReadOnly(m_RO); - public ReadOnlyCollection Data => Array.AsReadOnly(m_Data); + public byte[] Text { get; private set; } + public byte[] RO { get; private set; } + public byte[] Data { get; private set; } public int Mod0Offset { get; private set; } public int TextOffset { get; private set; } @@ -54,9 +48,9 @@ namespace Ryujinx.Core.Loaders.Executables return Reader.ReadBytes(Size); } - m_Text = Read(TextOffset, TextSize); - m_RO = Read(ROOffset, ROSize); - m_Data = Read(DataOffset, DataSize); + Text = Read(TextOffset, TextSize); + RO = Read(ROOffset, ROSize); + Data = Read(DataOffset, DataSize); } } } \ No newline at end of file diff --git a/Ryujinx.Core/Loaders/Executables/Nso.cs b/Ryujinx.Core/Loaders/Executables/Nso.cs index 7b8bf253a7..90174523eb 100644 --- a/Ryujinx.Core/Loaders/Executables/Nso.cs +++ b/Ryujinx.Core/Loaders/Executables/Nso.cs @@ -1,19 +1,14 @@ using Ryujinx.Core.Loaders.Compression; using System; -using System.Collections.ObjectModel; using System.IO; namespace Ryujinx.Core.Loaders.Executables { class Nso : IExecutable { - private byte[] m_Text; - private byte[] m_RO; - private byte[] m_Data; - - public ReadOnlyCollection Text => Array.AsReadOnly(m_Text); - public ReadOnlyCollection RO => Array.AsReadOnly(m_RO); - public ReadOnlyCollection Data => Array.AsReadOnly(m_Data); + public byte[] Text { get; private set; } + public byte[] RO { get; private set; } + public byte[] Data { get; private set; } public int Mod0Offset { get; private set; } public int TextOffset { get; private set; } @@ -82,38 +77,38 @@ namespace Ryujinx.Core.Loaders.Executables //Text segment Input.Seek(TextOffset, SeekOrigin.Begin); - m_Text = Reader.ReadBytes(TextSize); + Text = Reader.ReadBytes(TextSize); if (Flags.HasFlag(NsoFlags.IsTextCompressed) || true) { - m_Text = Lz4.Decompress(m_Text, TextDecSize); + Text = Lz4.Decompress(Text, TextDecSize); } //Read-only data segment Input.Seek(ROOffset, SeekOrigin.Begin); - m_RO = Reader.ReadBytes(ROSize); + RO = Reader.ReadBytes(ROSize); if (Flags.HasFlag(NsoFlags.IsROCompressed) || true) { - m_RO = Lz4.Decompress(m_RO, RODecSize); + RO = Lz4.Decompress(RO, RODecSize); } //Data segment Input.Seek(DataOffset, SeekOrigin.Begin); - m_Data = Reader.ReadBytes(DataSize); + Data = Reader.ReadBytes(DataSize); if (Flags.HasFlag(NsoFlags.IsDataCompressed) || true) { - m_Data = Lz4.Decompress(m_Data, DataDecSize); + Data = Lz4.Decompress(Data, DataDecSize); } - using (MemoryStream Text = new MemoryStream(m_Text)) + using (MemoryStream TextSegm = new MemoryStream(Text)) { - BinaryReader TextReader = new BinaryReader(Text); + BinaryReader TextReader = new BinaryReader(TextSegm); - Text.Seek(4, SeekOrigin.Begin); + TextSegm.Seek(4, SeekOrigin.Begin); Mod0Offset = TextReader.ReadInt32(); } diff --git a/Ryujinx.Core/OsHle/Handles/HSharedMem.cs b/Ryujinx.Core/OsHle/Handles/HSharedMem.cs index eb173e9652..7972a30b2e 100644 --- a/Ryujinx.Core/OsHle/Handles/HSharedMem.cs +++ b/Ryujinx.Core/OsHle/Handles/HSharedMem.cs @@ -1,43 +1,12 @@ -using System; -using System.Collections.Generic; - namespace Ryujinx.Core.OsHle.Handles { class HSharedMem { - private List Positions; + public long PA { get; private set; } - public EventHandler MemoryMapped; - public EventHandler MemoryUnmapped; - - public HSharedMem() + public HSharedMem(long PA) { - Positions = new List(); - } - - public void AddVirtualPosition(long Position) - { - lock (Positions) - { - Positions.Add(Position); - - MemoryMapped?.Invoke(this, EventArgs.Empty); - } - } - - public void RemoveVirtualPosition(long Position) - { - lock (Positions) - { - Positions.Remove(Position); - - MemoryUnmapped?.Invoke(this, EventArgs.Empty); - } - } - - public long[] GetVirtualPositions() - { - return Positions.ToArray(); + this.PA = PA; } } } \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Homebrew.cs b/Ryujinx.Core/OsHle/Homebrew.cs index e2e95e4d41..add55027d5 100644 --- a/Ryujinx.Core/OsHle/Homebrew.cs +++ b/Ryujinx.Core/OsHle/Homebrew.cs @@ -7,7 +7,7 @@ namespace Ryujinx.Core.OsHle //http://switchbrew.org/index.php?title=Homebrew_ABI public static void WriteHbAbiData(AMemory Memory, long Position, int MainThreadHandle) { - Memory.Manager.Map(Position, AMemoryMgr.PageSize, (int)MemoryType.Normal, AMemoryPerm.RW); + Memory.Manager.MapDirectRW(Position, AMemoryMgr.PageSize, (int)MemoryType.Normal); //MainThreadHandle WriteConfigEntry(Memory, ref Position, 1, 0, MainThreadHandle); diff --git a/Ryujinx.Core/OsHle/Horizon.cs b/Ryujinx.Core/OsHle/Horizon.cs index a8f5df7c9d..0b42bbae64 100644 --- a/Ryujinx.Core/OsHle/Horizon.cs +++ b/Ryujinx.Core/OsHle/Horizon.cs @@ -47,11 +47,11 @@ namespace Ryujinx.Core.OsHle Processes = new ConcurrentDictionary(); - HidSharedMem = new HSharedMem(); + HidSharedMem = new HSharedMem(Ns.Hid.PA); HidHandle = Handles.GenerateId(HidSharedMem); - FontHandle = Handles.GenerateId(new HSharedMem()); + FontHandle = Handles.GenerateId(new HSharedMem(0x5000)); } public void LoadCart(string ExeFsDir, string RomFsFile = null) diff --git a/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs b/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs index cc26df1082..ebb3dbca04 100644 --- a/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs +++ b/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs @@ -217,16 +217,26 @@ namespace Ryujinx.Core.OsHle.Ipc public long GetSendBuffPtr() { - if (SendBuff.Count > 0 && SendBuff[0].Position != 0) + if (SendBuff.Count > 0 && SendBuff[0].Size != 0) { return SendBuff[0].Position; } - if (PtrBuff.Count > 0 && PtrBuff[0].Position != 0) + if (PtrBuff.Count > 0 && PtrBuff[0].Size != 0) { return PtrBuff[0].Position; } + if (ReceiveBuff.Count > 0 && ReceiveBuff[0].Size != 0) + { + return ReceiveBuff[0].Position; + } + + if (RecvListBuff.Count > 0 && RecvListBuff[0].Size != 0) + { + return RecvListBuff[0].Position; + } + return -1; } } diff --git a/Ryujinx.Core/OsHle/MemoryRegions.cs b/Ryujinx.Core/OsHle/MemoryRegions.cs index 7f5ab0edeb..8bbc19e3e8 100644 --- a/Ryujinx.Core/OsHle/MemoryRegions.cs +++ b/Ryujinx.Core/OsHle/MemoryRegions.cs @@ -1,17 +1,18 @@ -using ChocolArm64.Memory; - namespace Ryujinx.Core.OsHle { static class MemoryRegions { + public const long RamSize = 1L << 32; public const long AddrSpaceStart = 0x08000000; + public const int AddrSpaceBits = 38; + public const long AddrSpaceSize = 1L << AddrSpaceBits; public const long MapRegionAddress = 0x10000000; public const long MapRegionSize = 0x20000000; public const long MainStackSize = 0x100000; - public const long MainStackAddress = AMemoryMgr.AddrSize - MainStackSize; + public const long MainStackAddress = RamSize - MainStackSize; public const long TlsPagesSize = 0x4000; @@ -21,8 +22,8 @@ namespace Ryujinx.Core.OsHle public const long TotalMemoryUsed = HeapRegionAddress + TlsPagesSize + MainStackSize; - public const long TotalMemoryAvailable = AMemoryMgr.RamSize - AddrSpaceStart; + public const long TotalMemoryAvailable = RamSize - AddrSpaceStart; - public const long AddrSpaceSize = AMemoryMgr.AddrSize - AddrSpaceStart; + } } \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Process.cs b/Ryujinx.Core/OsHle/Process.cs index f549b02792..afc062405b 100644 --- a/Ryujinx.Core/OsHle/Process.cs +++ b/Ryujinx.Core/OsHle/Process.cs @@ -45,7 +45,7 @@ namespace Ryujinx.Core.OsHle this.Ns = Ns; this.ProcessId = ProcessId; - Memory = new AMemory(Ns.Ram); + Memory = new AMemory(Ns.Ram, MemoryRegions.RamSize, MemoryRegions.AddrSpaceBits); Scheduler = new KProcessScheduler(); @@ -59,10 +59,10 @@ namespace Ryujinx.Core.OsHle ImageBase = MemoryRegions.AddrSpaceStart; - MapRWMemRegion( + Memory.Manager.MapDirectRW( MemoryRegions.TlsPagesAddress, MemoryRegions.TlsPagesSize, - MemoryType.ThreadLocal); + (int)MemoryType.ThreadLocal); } public void LoadProgram(IExecutable Program) @@ -88,10 +88,10 @@ namespace Ryujinx.Core.OsHle return false; } - MapRWMemRegion( + Memory.Manager.MapDirectRW( MemoryRegions.MainStackAddress, MemoryRegions.MainStackSize, - MemoryType.Normal); + (int)MemoryType.Normal); long StackTop = MemoryRegions.MainStackAddress + MemoryRegions.MainStackSize; @@ -119,11 +119,6 @@ namespace Ryujinx.Core.OsHle return true; } - private void MapRWMemRegion(long Position, long Size, MemoryType Type) - { - Memory.Manager.Map(Position, Size, (int)Type, AMemoryPerm.RW); - } - public void StopAllThreads() { if (MainThread != null) diff --git a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs index 515c15e034..3c0c46fec9 100644 --- a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs +++ b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs @@ -81,7 +81,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices FileDesc FdData = Context.Ns.Os.Fds.GetData(Fd); - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); Context.ResponseData.Write(0); @@ -139,7 +139,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuAsIoctlBindChannel(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); int Fd = Context.Memory.ReadInt32(Position); @@ -148,7 +148,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuAsIoctlAllocSpace(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); @@ -174,7 +174,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuAsIoctlMapBufferEx(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); @@ -207,7 +207,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuAsIoctlGetVaRegions(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); MemWriter Writer = new MemWriter(Context.Memory, Position); @@ -237,7 +237,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuAsIoctlInitializeEx(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); @@ -254,7 +254,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvHostIoctlCtrlGetConfig(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); MemWriter Writer = new MemWriter(Context.Memory, Position + 0x82); @@ -269,7 +269,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvHostIoctlCtrlEventWait(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); @@ -285,7 +285,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuIoctlZcullGetCtxSize(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); Context.Memory.WriteInt32(Position, 1); @@ -294,7 +294,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuIoctlZcullGetInfo(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemWriter Writer = new MemWriter(Context.Memory, Position); @@ -314,7 +314,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuIoctlGetCharacteristics(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); MemWriter Writer = new MemWriter(Context.Memory, Position); @@ -376,7 +376,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuIoctlGetTpcMasks(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); @@ -390,7 +390,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuIoctlZbcGetActiveSlotMask(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); Context.Memory.WriteInt32(Position + 0, 7); Context.Memory.WriteInt32(Position + 4, 1); @@ -400,14 +400,14 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvMapIoctlChannelSetUserData(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); return 0; } private static long NvMapIoctlChannelSetNvMap(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); int Fd = Context.Memory.ReadInt32(Position); @@ -416,7 +416,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvMapIoctlChannelSubmitGpFifo(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); MemWriter Writer = new MemWriter(Context.Memory, Position + 0x10); @@ -455,7 +455,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvMapIoctlChannelAllocObjCtx(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); int ClassNum = Context.Memory.ReadInt32(Position + 0); int Flags = Context.Memory.ReadInt32(Position + 4); @@ -467,7 +467,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvMapIoctlChannelZcullBind(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); @@ -480,7 +480,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvMapIoctlChannelSetErrorNotifier(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); @@ -494,7 +494,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvMapIoctlChannelSetPriority(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); int Priority = Context.Memory.ReadInt32(Position); @@ -503,7 +503,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvMapIoctlChannelAllocGpFifoEx2(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); MemWriter Writer = new MemWriter(Context.Memory, Position + 0xc); diff --git a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs index 740a35f9c4..6d75e50549 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs @@ -268,7 +268,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android HNvMap NvMap = GetNvMap(Context, Slot); - if (FbSize < 0 || NvMap.Address < 0 || NvMap.Address + FbSize > AMemoryMgr.AddrSize) + if (FbSize < 0 || NvMap.Address < 0 || NvMap.Address + FbSize > MemoryRegions.AddrSpaceSize) { Logging.Error($"Frame buffer address {NvMap.Address:x16} is invalid!"); diff --git a/Ryujinx.Core/OsHle/Svc/SvcMemory.cs b/Ryujinx.Core/OsHle/Svc/SvcMemory.cs index bf946e4f86..9b4e434795 100644 --- a/Ryujinx.Core/OsHle/Svc/SvcMemory.cs +++ b/Ryujinx.Core/OsHle/Svc/SvcMemory.cs @@ -16,7 +16,7 @@ namespace Ryujinx.Core.OsHle.Svc if (Size > CurrentHeapSize) { - Memory.Manager.Map(Position, Size, (int)MemoryType.Heap, AMemoryPerm.RW); + Memory.Manager.MapDirectRW(Position, Size, (int)MemoryType.Heap); } else { @@ -57,7 +57,9 @@ namespace Ryujinx.Core.OsHle.Svc AMemoryMapInfo SrcInfo = Memory.Manager.GetMapInfo(Src); - Memory.Manager.Map(Dst, Size, (int)MemoryType.MappedMemory, SrcInfo.Perm); + long PA = Memory.Manager.TranslatePosition(Src); + + Memory.Manager.Map(Dst, PA, Size, (int)MemoryType.MappedMemory, SrcInfo.Perm); Memory.Manager.Reprotect(Src, Size, AMemoryPerm.None); @@ -122,11 +124,9 @@ namespace Ryujinx.Core.OsHle.Svc if (SharedMem != null) { - AMemoryHelper.FillWithZeros(Memory, Src, (int)Size); + long PA = SharedMem.PA; - SharedMem.AddVirtualPosition(Src); - - Memory.Manager.Map(Src, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm); + Memory.Manager.Map(Src, PA, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm); ThreadState.X0 = 0; } diff --git a/Ryujinx.Core/PerformanceStatistics.cs b/Ryujinx.Core/PerformanceStatistics.cs index 3740daa584..e5d930f934 100644 --- a/Ryujinx.Core/PerformanceStatistics.cs +++ b/Ryujinx.Core/PerformanceStatistics.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; +using System.Diagnostics; using System.Timers; namespace Ryujinx.Core diff --git a/Ryujinx.Core/Switch.cs b/Ryujinx.Core/Switch.cs index 1acd87f018..941a8fceca 100644 --- a/Ryujinx.Core/Switch.cs +++ b/Ryujinx.Core/Switch.cs @@ -1,4 +1,3 @@ -using ChocolArm64.Memory; using Ryujinx.Core.Input; using Ryujinx.Core.OsHle; using Ryujinx.Core.Settings; @@ -25,21 +24,18 @@ namespace Ryujinx.Core public Switch(IGalRenderer Renderer) { - Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize); + Ram = Marshal.AllocHGlobal((IntPtr)MemoryRegions.RamSize); Gpu = new NsGpu(Renderer); VFs = new VirtualFs(); - Hid = new Hid(Ram); + Hid = new Hid(Ram, 0); Statistics = new PerformanceStatistics(); Os = new Horizon(this); - Os.HidSharedMem.MemoryMapped += Hid.ShMemMap; - Os.HidSharedMem.MemoryUnmapped += Hid.ShMemUnmap; - Settings = new SetSys(); } diff --git a/Ryujinx.Tests/Cpu/CpuTest.cs b/Ryujinx.Tests/Cpu/CpuTest.cs index a4a3b33fc5..545d827ef1 100644 --- a/Ryujinx.Tests/Cpu/CpuTest.cs +++ b/Ryujinx.Tests/Cpu/CpuTest.cs @@ -28,10 +28,12 @@ namespace Ryujinx.Tests.Cpu EntryPoint = Position; - Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize); + long RamSize = 32 * 1024 * 1024; + + Ram = Marshal.AllocHGlobal((IntPtr)RamSize); ATranslator Translator = new ATranslator(); - Memory = new AMemory(Ram); - Memory.Manager.Map(Position, Size, 2, AMemoryPerm.Read | AMemoryPerm.Write | AMemoryPerm.Execute); + Memory = new AMemory(Ram, RamSize, 32); + Memory.Manager.MapDirectRW(Position, Size, 2); Thread = new AThread(Translator, Memory, ThreadPriority.Normal, EntryPoint); }