diff --git a/Ryujinx/Cpu/Exceptions/VmmAccessViolationException.cs b/Ryujinx/Cpu/Exceptions/VmmAccessViolationException.cs index dd9d7a646..a557502e5 100644 --- a/Ryujinx/Cpu/Exceptions/VmmAccessViolationException.cs +++ b/Ryujinx/Cpu/Exceptions/VmmAccessViolationException.cs @@ -5,7 +5,7 @@ namespace ChocolArm64.Exceptions { public class VmmAccessViolationException : Exception { - private const string ExMsg = "Value at address 0x{0:x16} could not be \"{1}\"!"; + private const string ExMsg = "Address 0x{0:x16} does not have \"{1}\" permission!"; public VmmAccessViolationException() { } diff --git a/Ryujinx/Cpu/Memory/AMemoryMapInfo.cs b/Ryujinx/Cpu/Memory/AMemoryMapInfo.cs index 8ba6c25e6..44b2cc079 100644 --- a/Ryujinx/Cpu/Memory/AMemoryMapInfo.cs +++ b/Ryujinx/Cpu/Memory/AMemoryMapInfo.cs @@ -5,14 +5,16 @@ namespace ChocolArm64.Memory public long Position { get; private set; } public long Size { get; private set; } public int Type { get; private set; } + public int Attr { get; private set; } public AMemoryPerm Perm { get; private set; } - public AMemoryMapInfo(long Position, long Size, int Type, AMemoryPerm Perm) + public AMemoryMapInfo(long Position, long Size, int Type, int Attr, AMemoryPerm Perm) { this.Position = Position; this.Size = Size; this.Type = Type; + this.Attr = Attr; this.Perm = Perm; } } diff --git a/Ryujinx/Cpu/Memory/AMemoryMgr.cs b/Ryujinx/Cpu/Memory/AMemoryMgr.cs index 544e51302..05284059e 100644 --- a/Ryujinx/Cpu/Memory/AMemoryMgr.cs +++ b/Ryujinx/Cpu/Memory/AMemoryMgr.cs @@ -1,5 +1,3 @@ -using System.Runtime.CompilerServices; - namespace ChocolArm64.Memory { public class AMemoryMgr @@ -27,24 +25,23 @@ namespace ChocolArm64.Memory private enum PTMap { Unmapped, - Physical, - Mirror + Mapped } private struct PTEntry { - public long Position; - public int Type; - public PTMap Map; public AMemoryPerm Perm; - public PTEntry(long Position, int Type, PTMap Map, AMemoryPerm Perm) + public int Type; + public int Attr; + + public PTEntry(PTMap Map, AMemoryPerm Perm, int Type, int Attr) { - this.Position = Position; - this.Type = Type; - this.Map = Map; - this.Perm = Perm; + this.Map = Map; + this.Perm = Perm; + this.Type = Type; + this.Attr = Attr; } } @@ -53,7 +50,7 @@ namespace ChocolArm64.Memory private bool IsHeapInitialized; public long HeapAddr { get; private set; } - public int HeapSize { get; private set; } + public long HeapSize { get; private set; } public AMemoryMgr(AMemoryAlloc Allocator) { @@ -101,10 +98,10 @@ namespace ChocolArm64.Memory return false; } - public void SetHeapSize(int Size, int Type) + public void SetHeapSize(long Size, int Type) { //TODO: Return error when theres no enough space to allocate heap. - Size = (int)AMemoryHelper.PageRoundUp(Size); + Size = AMemoryHelper.PageRoundUp(Size); long Position = HeapAddr; @@ -132,40 +129,13 @@ namespace ChocolArm64.Memory HeapSize = Size; } - public bool MapPhys(long Src, long Dst, long Size, int Type, AMemoryPerm Perm) - { - Src = AMemoryHelper.PageRoundDown(Src); - Dst = AMemoryHelper.PageRoundDown(Dst); - - Size = AMemoryHelper.PageRoundUp(Size); - - if (Dst < 0 || Dst + Size >= RamSize) - { - return false; - } - - long PagesCount = Size / PageSize; - - while (PagesCount-- > 0) - { - SetPTEntry(Src, new PTEntry(Dst, Type, PTMap.Physical, Perm)); - - Src += PageSize; - Dst += PageSize; - } - - return true; - } - public void MapPhys(long Position, long Size, int Type, AMemoryPerm Perm) { while (Size > 0) { if (!IsMapped(Position)) { - long PhysPos = Allocator.Alloc(PageSize); - - SetPTEntry(Position, new PTEntry(PhysPos, Type, PTMap.Physical, Perm)); + SetPTEntry(Position, new PTEntry(PTMap.Mapped, Perm, Type, 0)); } long CPgSize = PageSize - (Position & PageMask); @@ -186,13 +156,19 @@ namespace ChocolArm64.Memory while (PagesCount-- > 0) { - PTEntry Entry = GetPTEntry(Src); + PTEntry SrcEntry = GetPTEntry(Src); + PTEntry DstEntry = GetPTEntry(Dst); - Entry.Type = Type; - Entry.Map = PTMap.Mirror; - Entry.Position = Dst; + DstEntry.Map = PTMap.Mapped; + DstEntry.Type = Type; + DstEntry.Perm = SrcEntry.Perm; - SetPTEntry(Src, Entry); + SrcEntry.Perm = AMemoryPerm.None; + + SrcEntry.Attr |= 1; + + SetPTEntry(Src, SrcEntry); + SetPTEntry(Dst, DstEntry); Src += PageSize; Dst += PageSize; @@ -229,9 +205,10 @@ namespace ChocolArm64.Memory { PTEntry Entry = GetPTEntry(Pos); - return Entry.Type == BaseEntry.Type && - Entry.Map == BaseEntry.Map && - Entry.Perm == BaseEntry.Perm; + return Entry.Map == BaseEntry.Map && + Entry.Perm == BaseEntry.Perm && + Entry.Type == BaseEntry.Type && + Entry.Attr == BaseEntry.Attr; } long Start = Position; @@ -249,7 +226,12 @@ namespace ChocolArm64.Memory long Size = End - Start; - return new AMemoryMapInfo(Start, Size, BaseEntry.Type, BaseEntry.Perm); + return new AMemoryMapInfo( + Start, + Size, + BaseEntry.Type, + BaseEntry.Attr, + BaseEntry.Perm); } public bool HasPermission(long Position, AMemoryPerm Perm) @@ -257,7 +239,6 @@ namespace ChocolArm64.Memory return GetPTEntry(Position).Perm.HasFlag(Perm); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsMapped(long Position) { if (Position >> PTLvl0Bits + PTLvl1Bits + PTPageBits != 0) @@ -276,7 +257,6 @@ namespace ChocolArm64.Memory return PageTable[L0][L1].Map != PTMap.Unmapped; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] private PTEntry GetPTEntry(long Position) { long L0 = (Position >> PTLvl0Bit) & PTLvl0Mask; @@ -290,7 +270,6 @@ namespace ChocolArm64.Memory return PageTable[L0][L1]; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] private void SetPTEntry(long Position, PTEntry Entry) { long L0 = (Position >> PTLvl0Bit) & PTLvl0Mask; diff --git a/Ryujinx/Gpu/NsGpuMemoryMgr.cs b/Ryujinx/Gpu/NsGpuMemoryMgr.cs index e555f2af3..563a5c099 100644 --- a/Ryujinx/Gpu/NsGpuMemoryMgr.cs +++ b/Ryujinx/Gpu/NsGpuMemoryMgr.cs @@ -1,5 +1,3 @@ -using System.Runtime.CompilerServices; - namespace Ryujinx.Gpu { class NsGpuMemoryMgr @@ -16,7 +14,7 @@ namespace Ryujinx.Gpu private const int PTLvl0Mask = PTLvl0Size - 1; private const int PTLvl1Mask = PTLvl1Size - 1; - private const int PageMask = PageSize - 1; + private const int PageMask = PageSize - 1; private const int PTLvl0Bit = PTPageBits + PTLvl0Bits; private const int PTLvl1Bit = PTPageBits; @@ -107,6 +105,11 @@ namespace Ryujinx.Gpu long Position = 0; long FreeSize = 0; + if (Align < 1) + { + Align = 1; + } + Align = (Align + PageMask) & ~PageMask; while (Position + FreeSize < AddrSize) @@ -149,7 +152,6 @@ namespace Ryujinx.Gpu return BasePos + (Position & PageMask); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool HasPTAddr(long Position) { if (Position >> PTLvl0Bits + PTLvl1Bits + PTPageBits != 0) @@ -168,7 +170,6 @@ namespace Ryujinx.Gpu return PageTable[L0][L1] != PteUnmapped; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] private long GetPTAddr(long Position) { long L0 = (Position >> PTLvl0Bit) & PTLvl0Mask; @@ -182,7 +183,6 @@ namespace Ryujinx.Gpu return PageTable[L0][L1]; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] private void SetPTAddr(long Position, long TgtAddr) { long L0 = (Position >> PTLvl0Bit) & PTLvl0Mask; diff --git a/Ryujinx/OsHle/MemoryInfo.cs b/Ryujinx/OsHle/MemoryInfo.cs index adf863b27..395ccf73e 100644 --- a/Ryujinx/OsHle/MemoryInfo.cs +++ b/Ryujinx/OsHle/MemoryInfo.cs @@ -18,7 +18,7 @@ namespace Ryujinx.OsHle BaseAddress = MapInfo.Position; Size = MapInfo.Size; MemType = MapInfo.Type; - MemAttr = 0; + MemAttr = MapInfo.Attr; MemPerm = (int)MapInfo.Perm; IpcRefCount = 0; DeviceRefCount = 0; diff --git a/Ryujinx/OsHle/Svc/SvcMemory.cs b/Ryujinx/OsHle/Svc/SvcMemory.cs index 70988eb0b..185cac892 100644 --- a/Ryujinx/OsHle/Svc/SvcMemory.cs +++ b/Ryujinx/OsHle/Svc/SvcMemory.cs @@ -8,7 +8,7 @@ namespace Ryujinx.OsHle.Svc { private static void SvcSetHeapSize(Switch Ns, ARegisters Registers, AMemory Memory) { - int Size = (int)Registers.X1; + uint Size = (uint)Registers.X1; Memory.Manager.SetHeapSize(Size, (int)MemoryType.Heap); @@ -30,8 +30,8 @@ namespace Ryujinx.OsHle.Svc private static void SvcMapMemory(Switch Ns, ARegisters Registers, AMemory Memory) { - long Src = (long)Registers.X0; - long Dst = (long)Registers.X1; + long Dst = (long)Registers.X0; + long Src = (long)Registers.X1; long Size = (long)Registers.X2; Memory.Manager.MapMirror(Src, Dst, Size, (int)MemoryType.MappedMemory); @@ -79,11 +79,9 @@ namespace Ryujinx.OsHle.Svc HndData.VirtPos = Src; - if (Memory.Manager.MapPhys(Src, Dst, Size, - (int)MemoryType.SharedMemory, (AMemoryPerm)Perm)) - { - Registers.X0 = (int)SvcResult.Success; - } + Memory.Manager.MapPhys(Position, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm); + + Registers.X0 = (int)SvcResult.Success; } //TODO: Error codes.