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/Common | |
| 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/Common')
| -rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Common/KAutoObject.cs | 21 | ||||
| -rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Common/KResourceLimit.cs | 14 | ||||
| -rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Common/KSynchronizationObject.cs | 2 | ||||
| -rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Common/KernelResult.cs | 57 | ||||
| -rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Common/KernelTransfer.cs | 20 |
5 files changed, 78 insertions, 36 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Common/KAutoObject.cs b/Ryujinx.HLE/HOS/Kernel/Common/KAutoObject.cs index ddb0c71f..3b30dd80 100644 --- a/Ryujinx.HLE/HOS/Kernel/Common/KAutoObject.cs +++ b/Ryujinx.HLE/HOS/Kernel/Common/KAutoObject.cs @@ -1,12 +1,18 @@ +using System.Threading; + namespace Ryujinx.HLE.HOS.Kernel.Common { class KAutoObject { protected Horizon System; + private int _referenceCount; + public KAutoObject(Horizon system) { System = system; + + _referenceCount = 1; } public virtual KernelResult SetName(string name) @@ -38,5 +44,20 @@ namespace Ryujinx.HLE.HOS.Kernel.Common return null; } + + public void IncrementReferenceCount() + { + Interlocked.Increment(ref _referenceCount); + } + + public void DecrementReferenceCount() + { + if (Interlocked.Decrement(ref _referenceCount) == 0) + { + Destroy(); + } + } + + protected virtual void Destroy() { } } }
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/Common/KResourceLimit.cs b/Ryujinx.HLE/HOS/Kernel/Common/KResourceLimit.cs index 01bba65f..a7955d7a 100644 --- a/Ryujinx.HLE/HOS/Kernel/Common/KResourceLimit.cs +++ b/Ryujinx.HLE/HOS/Kernel/Common/KResourceLimit.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Kernel.Common { - class KResourceLimit + class KResourceLimit : KAutoObject { private const int Time10SecondsMs = 10000; @@ -18,9 +18,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Common private int _waitingThreadsCount; - private Horizon _system; - - public KResourceLimit(Horizon system) + public KResourceLimit(Horizon system) : base(system) { _current = new long[(int)LimitableResource.Count]; _limit = new long[(int)LimitableResource.Count]; @@ -29,8 +27,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Common _lockObj = new object(); _waitingThreads = new LinkedList<KThread>(); - - _system = system; } public bool Reserve(LimitableResource resource, ulong amount) @@ -61,7 +57,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Common { _waitingThreadsCount++; - KConditionVariable.Wait(_system, _waitingThreads, _lockObj, timeout); + KConditionVariable.Wait(System, _waitingThreads, _lockObj, timeout); _waitingThreadsCount--; @@ -94,7 +90,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Common Release(resource, amount, amount); } - private void Release(LimitableResource resource, long usedAmount, long availableAmount) + public void Release(LimitableResource resource, long usedAmount, long availableAmount) { int index = GetIndex(resource); @@ -105,7 +101,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Common if (_waitingThreadsCount > 0) { - KConditionVariable.NotifyAll(_system, _waitingThreads); + KConditionVariable.NotifyAll(System, _waitingThreads); } } } diff --git a/Ryujinx.HLE/HOS/Kernel/Common/KSynchronizationObject.cs b/Ryujinx.HLE/HOS/Kernel/Common/KSynchronizationObject.cs index 87e55312..77d8fbff 100644 --- a/Ryujinx.HLE/HOS/Kernel/Common/KSynchronizationObject.cs +++ b/Ryujinx.HLE/HOS/Kernel/Common/KSynchronizationObject.cs @@ -5,7 +5,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Common { class KSynchronizationObject : KAutoObject { - public LinkedList<KThread> WaitingThreads; + public LinkedList<KThread> WaitingThreads { get; } public KSynchronizationObject(Horizon system) : base(system) { diff --git a/Ryujinx.HLE/HOS/Kernel/Common/KernelResult.cs b/Ryujinx.HLE/HOS/Kernel/Common/KernelResult.cs index cea24693..357b01ea 100644 --- a/Ryujinx.HLE/HOS/Kernel/Common/KernelResult.cs +++ b/Ryujinx.HLE/HOS/Kernel/Common/KernelResult.cs @@ -2,31 +2,36 @@ namespace Ryujinx.HLE.HOS.Kernel.Common { enum KernelResult { - Success = 0, - InvalidCapability = 0x1c01, - ThreadNotStarted = 0x7201, - ThreadTerminating = 0x7601, - InvalidSize = 0xca01, - InvalidAddress = 0xcc01, - OutOfResource = 0xce01, - OutOfMemory = 0xd001, - HandleTableFull = 0xd201, - InvalidMemState = 0xd401, - InvalidPermission = 0xd801, - InvalidMemRange = 0xdc01, - InvalidPriority = 0xe001, - InvalidCpuCore = 0xe201, - InvalidHandle = 0xe401, - UserCopyFailed = 0xe601, - InvalidCombination = 0xe801, - TimedOut = 0xea01, - Cancelled = 0xec01, - MaximumExceeded = 0xee01, - InvalidEnumValue = 0xf001, - NotFound = 0xf201, - InvalidThread = 0xf401, - InvalidState = 0xfa01, - ReservedValue = 0xfc01, - ResLimitExceeded = 0x10801 + Success = 0, + SessionCountExceeded = 0xe01, + InvalidCapability = 0x1c01, + ThreadNotStarted = 0x7201, + ThreadTerminating = 0x7601, + InvalidSize = 0xca01, + InvalidAddress = 0xcc01, + OutOfResource = 0xce01, + OutOfMemory = 0xd001, + HandleTableFull = 0xd201, + InvalidMemState = 0xd401, + InvalidPermission = 0xd801, + InvalidMemRange = 0xdc01, + InvalidPriority = 0xe001, + InvalidCpuCore = 0xe201, + InvalidHandle = 0xe401, + UserCopyFailed = 0xe601, + InvalidCombination = 0xe801, + TimedOut = 0xea01, + Cancelled = 0xec01, + MaximumExceeded = 0xee01, + InvalidEnumValue = 0xf001, + NotFound = 0xf201, + InvalidThread = 0xf401, + PortRemoteClosed = 0xf601, + InvalidState = 0xfa01, + ReservedValue = 0xfc01, + PortClosed = 0x10601, + ResLimitExceeded = 0x10801, + OutOfVaSpace = 0x20601, + CmdBufferTooSmall = 0x20801 } }
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/Common/KernelTransfer.cs b/Ryujinx.HLE/HOS/Kernel/Common/KernelTransfer.cs index a29b1722..2b759140 100644 --- a/Ryujinx.HLE/HOS/Kernel/Common/KernelTransfer.cs +++ b/Ryujinx.HLE/HOS/Kernel/Common/KernelTransfer.cs @@ -22,6 +22,26 @@ namespace Ryujinx.HLE.HOS.Kernel.Common return false; } + public static bool UserToKernelInt32Array(Horizon system, ulong address, int[] values) + { + KProcess currentProcess = system.Scheduler.GetCurrentProcess(); + + for (int index = 0; index < values.Length; index++, address += 4) + { + if (currentProcess.CpuMemory.IsMapped((long)address) && + currentProcess.CpuMemory.IsMapped((long)address + 3)) + { + values[index]= currentProcess.CpuMemory.ReadInt32((long)address); + } + else + { + return false; + } + } + + return true; + } + public static bool UserToKernelString(Horizon system, ulong address, int size, out string value) { KProcess currentProcess = system.Scheduler.GetCurrentProcess(); |
