diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2019-01-18 20:26:39 -0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-01-18 20:26:39 -0200 |
| commit | 22bacc618815170c0d186a82e1ea4558e36b7063 (patch) | |
| tree | 79b97959481fea1ac301da6d4e9dea9b991ece6f /Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlock.cs | |
| parent | 3731d0ce8412c3c48286c242842bcb4940b4ca6d (diff) | |
Improve kernel IPC implementation (#550)
* Implement some IPC related kernel SVCs properly
* Fix BLZ decompression when the segment also has a uncompressed chunck
* Set default cpu core on process start from ProgramLoader, remove debug message
* Load process capabilities properly on KIPs
* Fix a copy/paste error in UnmapPhysicalMemory64
* Implement smarter switching between old and new IPC system to support the old HLE services implementation without the manual switch
* Implement RegisterService on sm and AcceptSession (partial)
* Misc fixes and improvements on new IPC methods
* Move IPC related SVCs into a separate file, and logging on RegisterService (sm)
* Some small fixes related to receive list buffers and error cases
* Load NSOs using the correct pool partition
* Fix corner case on GetMaskFromMinMax where range is 64, doesn't happen in pratice however
* Fix send static buffer copy
* Session release, implement closing requests on client disconnect
* Implement ConnectToPort SVC
* KLightSession init
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlock.cs')
| -rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlock.cs | 106 |
1 files changed, 93 insertions, 13 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlock.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlock.cs index 89a19498..b7c2b309 100644 --- a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlock.cs +++ b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryBlock.cs @@ -1,29 +1,108 @@ +using System; + namespace Ryujinx.HLE.HOS.Kernel.Memory { class KMemoryBlock { - public ulong BaseAddress { get; set; } - public ulong PagesCount { get; set; } + public ulong BaseAddress { get; private set; } + public ulong PagesCount { get; private set; } - public MemoryState State { get; set; } - public MemoryPermission Permission { get; set; } - public MemoryAttribute Attribute { get; set; } + public MemoryState State { get; private set; } + public MemoryPermission Permission { get; private set; } + public MemoryAttribute Attribute { get; private set; } + public MemoryPermission SourcePermission { get; private set; } - public int IpcRefCount { get; set; } - public int DeviceRefCount { get; set; } + public int IpcRefCount { get; private set; } + public int DeviceRefCount { get; private set; } public KMemoryBlock( ulong baseAddress, ulong pagesCount, MemoryState state, MemoryPermission permission, - MemoryAttribute attribute) + MemoryAttribute attribute, + int ipcRefCount = 0, + int deviceRefCount = 0) + { + BaseAddress = baseAddress; + PagesCount = pagesCount; + State = state; + Attribute = attribute; + Permission = permission; + IpcRefCount = ipcRefCount; + DeviceRefCount = deviceRefCount; + } + + public void SetState(MemoryPermission permission, MemoryState state, MemoryAttribute attribute) + { + Permission = permission; + State = state; + Attribute &= MemoryAttribute.IpcAndDeviceMapped; + Attribute |= attribute; + } + + public void SetIpcMappingPermission(MemoryPermission permission) + { + int oldIpcRefCount = IpcRefCount++; + + if ((ushort)IpcRefCount == 0) + { + throw new InvalidOperationException("IPC reference count increment overflowed."); + } + + if (oldIpcRefCount == 0) + { + SourcePermission = permission; + + Permission &= ~MemoryPermission.ReadAndWrite; + Permission |= MemoryPermission.ReadAndWrite & permission; + } + + Attribute |= MemoryAttribute.IpcMapped; + } + + public void RestoreIpcMappingPermission() + { + int oldIpcRefCount = IpcRefCount--; + + if (oldIpcRefCount == 0) + { + throw new InvalidOperationException("IPC reference count decrement underflowed."); + } + + if (oldIpcRefCount == 1) + { + Permission = SourcePermission; + + SourcePermission = MemoryPermission.None; + + Attribute &= ~MemoryAttribute.IpcMapped; + } + } + + public KMemoryBlock SplitRightAtAddress(ulong address) + { + ulong leftAddress = BaseAddress; + + ulong leftPagesCount = (address - leftAddress) / KMemoryManager.PageSize; + + BaseAddress = address; + + PagesCount -= leftPagesCount; + + return new KMemoryBlock( + leftAddress, + leftPagesCount, + State, + Permission, + Attribute, + IpcRefCount, + DeviceRefCount); + } + + public void AddPages(ulong pagesCount) { - BaseAddress = baseAddress; - PagesCount = pagesCount; - State = state; - Attribute = attribute; - Permission = permission; + PagesCount += pagesCount; } public KMemoryInfo GetInfo() @@ -36,6 +115,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory State, Permission, Attribute, + SourcePermission, IpcRefCount, DeviceRefCount); } |
