diff options
author | Mary <me@thog.eu> | 2021-05-05 23:44:26 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-05 23:44:26 +0200 |
commit | b94dc01d4357c608d60383e85f709312294fd833 (patch) | |
tree | 3b4fff544218ed538fd8160498eddb3eba794fc0 /Ryujinx.HLE/HOS/Services/ServerBase.cs | |
parent | eb056218a13fa145adcc9ecafd166b1b1f2caccb (diff) |
SM instance & TIPC fixes (#2241)
This PR addresses the following issues:
- SM was previously instancied once and reused on all sessions. This
could cause inconsistency on the service initialization.
- TIPC replies were not matching what is generated on hardware.
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/ServerBase.cs')
-rw-r--r-- | Ryujinx.HLE/HOS/Services/ServerBase.cs | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/Ryujinx.HLE/HOS/Services/ServerBase.cs b/Ryujinx.HLE/HOS/Services/ServerBase.cs index f957a624..5b9834dc 100644 --- a/Ryujinx.HLE/HOS/Services/ServerBase.cs +++ b/Ryujinx.HLE/HOS/Services/ServerBase.cs @@ -35,10 +35,10 @@ namespace Ryujinx.HLE.HOS.Services private readonly List<int> _sessionHandles = new List<int>(); private readonly List<int> _portHandles = new List<int>(); private readonly Dictionary<int, IpcService> _sessions = new Dictionary<int, IpcService>(); - private readonly Dictionary<int, IpcService> _ports = new Dictionary<int, IpcService>(); + private readonly Dictionary<int, Func<IpcService>> _ports = new Dictionary<int, Func<IpcService>>(); public ManualResetEvent InitDone { get; } - public IpcService SmObject { get; set; } + public Func<IpcService> SmObjectFactory { get; set; } public string Name { get; } public ServerBase(KernelContext context, string name) @@ -58,10 +58,10 @@ namespace Ryujinx.HLE.HOS.Services KernelStatic.StartInitialProcess(context, creationInfo, DefaultCapabilities, 44, ServerLoop); } - private void AddPort(int serverPortHandle, IpcService obj) + private void AddPort(int serverPortHandle, Func<IpcService> objectFactory) { _portHandles.Add(serverPortHandle); - _ports.Add(serverPortHandle, obj); + _ports.Add(serverPortHandle, objectFactory); } public void AddSessionObj(KServerSession serverSession, IpcService obj) @@ -80,11 +80,11 @@ namespace Ryujinx.HLE.HOS.Services { _selfProcess = KernelStatic.GetCurrentProcess(); - if (SmObject != null) + if (SmObjectFactory != null) { _context.Syscall.ManageNamedPort("sm:", 50, out int serverPortHandle); - AddPort(serverPortHandle, SmObject); + AddPort(serverPortHandle, SmObjectFactory); InitDone.Set(); } @@ -141,7 +141,9 @@ namespace Ryujinx.HLE.HOS.Services // We got a new connection, accept the session to allow servicing future requests. if (_context.Syscall.AcceptSession(handles[signaledIndex], out int serverSessionHandle) == KernelResult.Success) { - AddSessionObj(serverSessionHandle, _ports[handles[signaledIndex]]); + IpcService obj = _ports[handles[signaledIndex]].Invoke(); + + AddSessionObj(serverSessionHandle, obj); } } @@ -191,6 +193,7 @@ namespace Ryujinx.HLE.HOS.Services } bool shouldReply = true; + bool isTipcCommunication = false; using (MemoryStream raw = new MemoryStream(request.RawData)) { @@ -269,6 +272,8 @@ namespace Ryujinx.HLE.HOS.Services // If the type is past 0xF, we are using TIPC else if (request.Type > IpcMessageType.TipcCloseSession) { + isTipcCommunication = true; + // Response type is always the same as request on TIPC. response.Type = request.Type; @@ -290,13 +295,19 @@ namespace Ryujinx.HLE.HOS.Services response.RawData = resMs.ToArray(); } + + process.CpuMemory.Write(messagePtr, response.GetBytesTipc()); } else { throw new NotImplementedException(request.Type.ToString()); } - process.CpuMemory.Write(messagePtr, response.GetBytes((long)messagePtr, recvListAddr | ((ulong)PointerBufferSize << 48))); + if (!isTipcCommunication) + { + process.CpuMemory.Write(messagePtr, response.GetBytes((long)messagePtr, recvListAddr | ((ulong)PointerBufferSize << 48))); + } + return shouldReply; } } |