Compare commits

...

2 Commits

Author SHA1 Message Date
Ac_K
1e06b28b22 Horizon: Migrate usb and psc services (#5800)
* Horizon: Migrate Usb and Psc services

* Fix formatting

* Adresses feedback
2023-10-13 23:13:15 -03:00
sunshineinabox
e768a54f17 Replace ReaderWriterLock with ReaderWriterLockSlim (#5785)
* Replace ReaderWriterLock with ReaderWriterLockSlim

* Resolve Feedback + Correct typo

* Revert some unncessary logic
2023-10-12 18:11:15 +02:00
68 changed files with 773 additions and 181 deletions

View File

@@ -7,14 +7,14 @@ namespace ARMeilleure.Translation
internal class TranslatorCache<T> internal class TranslatorCache<T>
{ {
private readonly IntervalTree<ulong, T> _tree; private readonly IntervalTree<ulong, T> _tree;
private readonly ReaderWriterLock _treeLock; private readonly ReaderWriterLockSlim _treeLock;
public int Count => _tree.Count; public int Count => _tree.Count;
public TranslatorCache() public TranslatorCache()
{ {
_tree = new IntervalTree<ulong, T>(); _tree = new IntervalTree<ulong, T>();
_treeLock = new ReaderWriterLock(); _treeLock = new ReaderWriterLockSlim();
} }
public bool TryAdd(ulong address, ulong size, T value) public bool TryAdd(ulong address, ulong size, T value)
@@ -24,70 +24,70 @@ namespace ARMeilleure.Translation
public bool AddOrUpdate(ulong address, ulong size, T value, Func<ulong, T, T> updateFactoryCallback) public bool AddOrUpdate(ulong address, ulong size, T value, Func<ulong, T, T> updateFactoryCallback)
{ {
_treeLock.AcquireWriterLock(Timeout.Infinite); _treeLock.EnterWriteLock();
bool result = _tree.AddOrUpdate(address, address + size, value, updateFactoryCallback); bool result = _tree.AddOrUpdate(address, address + size, value, updateFactoryCallback);
_treeLock.ReleaseWriterLock(); _treeLock.ExitWriteLock();
return result; return result;
} }
public T GetOrAdd(ulong address, ulong size, T value) public T GetOrAdd(ulong address, ulong size, T value)
{ {
_treeLock.AcquireWriterLock(Timeout.Infinite); _treeLock.EnterWriteLock();
value = _tree.GetOrAdd(address, address + size, value); value = _tree.GetOrAdd(address, address + size, value);
_treeLock.ReleaseWriterLock(); _treeLock.ExitWriteLock();
return value; return value;
} }
public bool Remove(ulong address) public bool Remove(ulong address)
{ {
_treeLock.AcquireWriterLock(Timeout.Infinite); _treeLock.EnterWriteLock();
bool removed = _tree.Remove(address) != 0; bool removed = _tree.Remove(address) != 0;
_treeLock.ReleaseWriterLock(); _treeLock.ExitWriteLock();
return removed; return removed;
} }
public void Clear() public void Clear()
{ {
_treeLock.AcquireWriterLock(Timeout.Infinite); _treeLock.EnterWriteLock();
_tree.Clear(); _tree.Clear();
_treeLock.ReleaseWriterLock(); _treeLock.ExitWriteLock();
} }
public bool ContainsKey(ulong address) public bool ContainsKey(ulong address)
{ {
_treeLock.AcquireReaderLock(Timeout.Infinite); _treeLock.EnterReadLock();
bool result = _tree.ContainsKey(address); bool result = _tree.ContainsKey(address);
_treeLock.ReleaseReaderLock(); _treeLock.ExitReadLock();
return result; return result;
} }
public bool TryGetValue(ulong address, out T value) public bool TryGetValue(ulong address, out T value)
{ {
_treeLock.AcquireReaderLock(Timeout.Infinite); _treeLock.EnterReadLock();
bool result = _tree.TryGet(address, out value); bool result = _tree.TryGet(address, out value);
_treeLock.ReleaseReaderLock(); _treeLock.ExitReadLock();
return result; return result;
} }
public int GetOverlaps(ulong address, ulong size, ref ulong[] overlaps) public int GetOverlaps(ulong address, ulong size, ref ulong[] overlaps)
{ {
_treeLock.AcquireReaderLock(Timeout.Infinite); _treeLock.EnterReadLock();
int count = _tree.Get(address, address + size, ref overlaps); int count = _tree.Get(address, address + size, ref overlaps);
_treeLock.ReleaseReaderLock(); _treeLock.ExitReadLock();
return count; return count;
} }
public List<T> AsList() public List<T> AsList()
{ {
_treeLock.AcquireReaderLock(Timeout.Infinite); _treeLock.EnterReadLock();
List<T> list = _tree.AsList(); List<T> list = _tree.AsList();
_treeLock.ReleaseReaderLock(); _treeLock.ExitReadLock();
return list; return list;
} }

View File

@@ -5,7 +5,7 @@ namespace Ryujinx.Common
{ {
public class ReactiveObject<T> public class ReactiveObject<T>
{ {
private readonly ReaderWriterLock _readerWriterLock = new(); private readonly ReaderWriterLockSlim _readerWriterLock = new();
private bool _isInitialized; private bool _isInitialized;
private T _value; private T _value;
@@ -15,15 +15,15 @@ namespace Ryujinx.Common
{ {
get get
{ {
_readerWriterLock.AcquireReaderLock(Timeout.Infinite); _readerWriterLock.EnterReadLock();
T value = _value; T value = _value;
_readerWriterLock.ReleaseReaderLock(); _readerWriterLock.ExitReadLock();
return value; return value;
} }
set set
{ {
_readerWriterLock.AcquireWriterLock(Timeout.Infinite); _readerWriterLock.EnterWriteLock();
T oldValue = _value; T oldValue = _value;
@@ -32,7 +32,7 @@ namespace Ryujinx.Common
_isInitialized = true; _isInitialized = true;
_value = value; _value = value;
_readerWriterLock.ReleaseWriterLock(); _readerWriterLock.ExitWriteLock();
if (!oldIsInitialized || oldValue == null || !oldValue.Equals(_value)) if (!oldIsInitialized || oldValue == null || !oldValue.Equals(_value))
{ {

View File

@@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Vulkan
private int _flushTemp; private int _flushTemp;
private int _lastFlushWrite = -1; private int _lastFlushWrite = -1;
private readonly ReaderWriterLock _flushLock; private readonly ReaderWriterLockSlim _flushLock;
private FenceHolder _flushFence; private FenceHolder _flushFence;
private int _flushWaiting; private int _flushWaiting;
@@ -85,7 +85,7 @@ namespace Ryujinx.Graphics.Vulkan
_currentType = currentType; _currentType = currentType;
DesiredType = currentType; DesiredType = currentType;
_flushLock = new ReaderWriterLock(); _flushLock = new ReaderWriterLockSlim();
_useMirrors = gd.IsTBDR; _useMirrors = gd.IsTBDR;
} }
@@ -106,7 +106,7 @@ namespace Ryujinx.Graphics.Vulkan
_currentType = currentType; _currentType = currentType;
DesiredType = currentType; DesiredType = currentType;
_flushLock = new ReaderWriterLock(); _flushLock = new ReaderWriterLockSlim();
} }
public bool TryBackingSwap(ref CommandBufferScoped? cbs) public bool TryBackingSwap(ref CommandBufferScoped? cbs)
@@ -116,7 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
// Only swap if the buffer is not used in any queued command buffer. // Only swap if the buffer is not used in any queued command buffer.
bool isRented = _buffer.HasRentedCommandBufferDependency(_gd.CommandBufferPool); bool isRented = _buffer.HasRentedCommandBufferDependency(_gd.CommandBufferPool);
if (!isRented && _gd.CommandBufferPool.OwnedByCurrentThread && !_flushLock.IsReaderLockHeld && (_pendingData == null || cbs != null)) if (!isRented && _gd.CommandBufferPool.OwnedByCurrentThread && !_flushLock.IsReadLockHeld && (_pendingData == null || cbs != null))
{ {
var currentAllocation = _allocationAuto; var currentAllocation = _allocationAuto;
var currentBuffer = _buffer; var currentBuffer = _buffer;
@@ -131,7 +131,7 @@ namespace Ryujinx.Graphics.Vulkan
ClearMirrors(cbs.Value, 0, Size); ClearMirrors(cbs.Value, 0, Size);
} }
_flushLock.AcquireWriterLock(Timeout.Infinite); _flushLock.EnterWriteLock();
ClearFlushFence(); ClearFlushFence();
@@ -185,7 +185,7 @@ namespace Ryujinx.Graphics.Vulkan
_gd.PipelineInternal.SwapBuffer(currentBuffer, _buffer); _gd.PipelineInternal.SwapBuffer(currentBuffer, _buffer);
_flushLock.ReleaseWriterLock(); _flushLock.ExitWriteLock();
} }
_swapQueued = false; _swapQueued = false;
@@ -548,42 +548,44 @@ namespace Ryujinx.Graphics.Vulkan
private void WaitForFlushFence() private void WaitForFlushFence()
{ {
// Assumes the _flushLock is held as reader, returns in same state. if (_flushFence == null)
{
return;
}
// If storage has changed, make sure the fence has been reached so that the data is in place.
_flushLock.ExitReadLock();
_flushLock.EnterWriteLock();
if (_flushFence != null) if (_flushFence != null)
{ {
// If storage has changed, make sure the fence has been reached so that the data is in place. var fence = _flushFence;
Interlocked.Increment(ref _flushWaiting);
var cookie = _flushLock.UpgradeToWriterLock(Timeout.Infinite); // Don't wait in the lock.
if (_flushFence != null) _flushLock.ExitWriteLock();
fence.Wait();
_flushLock.EnterWriteLock();
if (Interlocked.Decrement(ref _flushWaiting) == 0)
{ {
var fence = _flushFence; fence.Put();
Interlocked.Increment(ref _flushWaiting);
// Don't wait in the lock.
var restoreCookie = _flushLock.ReleaseLock();
fence.Wait();
_flushLock.RestoreLock(ref restoreCookie);
if (Interlocked.Decrement(ref _flushWaiting) == 0)
{
fence.Put();
}
_flushFence = null;
} }
_flushLock.DowngradeFromWriterLock(ref cookie); _flushFence = null;
} }
// Assumes the _flushLock is held as reader, returns in same state.
_flushLock.ExitWriteLock();
_flushLock.EnterReadLock();
} }
public PinnedSpan<byte> GetData(int offset, int size) public PinnedSpan<byte> GetData(int offset, int size)
{ {
_flushLock.AcquireReaderLock(Timeout.Infinite); _flushLock.EnterReadLock();
WaitForFlushFence(); WaitForFlushFence();
@@ -603,7 +605,7 @@ namespace Ryujinx.Graphics.Vulkan
// Need to be careful here, the buffer can't be unmapped while the data is being used. // Need to be careful here, the buffer can't be unmapped while the data is being used.
_buffer.IncrementReferenceCount(); _buffer.IncrementReferenceCount();
_flushLock.ReleaseReaderLock(); _flushLock.ExitReadLock();
return PinnedSpan<byte>.UnsafeFromSpan(result, _buffer.DecrementReferenceCount); return PinnedSpan<byte>.UnsafeFromSpan(result, _buffer.DecrementReferenceCount);
} }
@@ -621,7 +623,7 @@ namespace Ryujinx.Graphics.Vulkan
result = resource.GetFlushBuffer().GetBufferData(resource.GetPool(), this, offset, size); result = resource.GetFlushBuffer().GetBufferData(resource.GetPool(), this, offset, size);
} }
_flushLock.ReleaseReaderLock(); _flushLock.ExitReadLock();
// Flush buffer is pinned until the next GetBufferData on the thread, which is fine for current uses. // Flush buffer is pinned until the next GetBufferData on the thread, which is fine for current uses.
return PinnedSpan<byte>.UnsafeFromSpan(result); return PinnedSpan<byte>.UnsafeFromSpan(result);
@@ -1073,11 +1075,11 @@ namespace Ryujinx.Graphics.Vulkan
_allocationAuto.Dispose(); _allocationAuto.Dispose();
} }
_flushLock.AcquireWriterLock(Timeout.Infinite); _flushLock.EnterWriteLock();
ClearFlushFence(); ClearFlushFence();
_flushLock.ReleaseWriterLock(); _flushLock.ExitWriteLock();
} }
} }
} }

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Ins
{
[Service("ins:r")]
class IReceiverManager : IpcService
{
public IReceiverManager(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Ins
{
[Service("ins:s")]
class ISenderManager : IpcService
{
public ISenderManager(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Ovln
{
[Service("ovln:rcv")]
class IReceiverService : IpcService
{
public IReceiverService(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Ovln
{
[Service("ovln:snd")]
class ISenderService : IpcService
{
public ISenderService(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Psc
{
[Service("psc:c")]
class IPmControl : IpcService
{
public IPmControl(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Psc
{
[Service("psc:m")]
class IPmService : IpcService
{
public IPmService(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Psc
{
[Service("psc:l")] // 9.0.0+
class IPmUnknown : IpcService
{
public IPmUnknown(ServiceCtx context) { }
}
}

View File

@@ -1,9 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Srepo
{
[Service("srepo:a")] // 5.0.0+
[Service("srepo:u")] // 5.0.0+
class ISrepoService : IpcService
{
public ISrepoService(ServiceCtx context) { }
}
}

View File

@@ -1,9 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Usb
{
[Service("usb:hs")]
[Service("usb:hs:a")] // 7.0.0+
class IClientRootSession : IpcService
{
public IClientRootSession(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Usb
{
[Service("usb:ds")]
class IDsService : IpcService
{
public IDsService(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Usb
{
[Service("usb:pd:c")]
class IPdCradleManager : IpcService
{
public IPdCradleManager(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Usb
{
[Service("usb:pd")]
class IPdManager : IpcService
{
public IPdManager(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Usb
{
[Service("usb:pm")]
class IPmService : IpcService
{
public IPmService(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Usb
{
[Service("usb:qdb")] // 7.0.0+
class IUnknown1 : IpcService
{
public IUnknown1(ServiceCtx context) { }
}
}

View File

@@ -1,8 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Usb
{
[Service("usb:obsv")] // 8.0.0+
class IUnknown2 : IpcService
{
public IUnknown2(ServiceCtx context) { }
}
}

View File

@@ -93,7 +93,7 @@ namespace Ryujinx.Horizon.Generators.Hipc
generator.LeaveScope(); generator.LeaveScope();
generator.LeaveScope(); generator.LeaveScope();
context.AddSource($"{className}.g.cs", generator.ToString()); context.AddSource($"{GetNamespaceName(commandInterface.ClassDeclarationSyntax)}.{className}.g.cs", generator.ToString());
} }
} }

View File

@@ -0,0 +1,47 @@
using Ryujinx.Horizon.Hshl.Ipc;
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
namespace Ryujinx.Horizon.Hshl
{
class HshlIpcServer
{
private const int HshlMaxSessionsCount = 10;
private const int TotalMaxSessionsCount = HshlMaxSessionsCount * 2;
private const int PointerBufferSize = 0;
private const int MaxDomains = 0;
private const int MaxDomainObjects = 0;
private const int MaxPortsCount = 2;
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm;
private ServerManager _serverManager;
public void Initialize()
{
HeapAllocator allocator = new();
_sm = new SmApi();
_sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
#pragma warning disable IDE0055 // Disable formatting
_serverManager.RegisterObjectForServer(new SetterManager(), ServiceName.Encode("hshl:set"), HshlMaxSessionsCount); // 11.0.0+
_serverManager.RegisterObjectForServer(new Manager(), ServiceName.Encode("hshl:sys"), HshlMaxSessionsCount); // 11.0.0+
#pragma warning restore IDE0055
}
public void ServiceRequests()
{
_serverManager.ServiceRequests();
}
public void Shutdown()
{
_serverManager.Dispose();
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Ryujinx.Horizon.Hshl
{
class HshlMain : IService
{
public static void Main(ServiceTable serviceTable)
{
HshlIpcServer ipcServer = new();
ipcServer.Initialize();
serviceTable.SignalServiceReady();
ipcServer.ServiceRequests();
ipcServer.Shutdown();
}
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Hshl;
namespace Ryujinx.Horizon.Hshl.Ipc
{
partial class Manager : IManager
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Hshl;
namespace Ryujinx.Horizon.Hshl.Ipc
{
partial class SetterManager : ISetterManager
{
}
}

View File

@@ -0,0 +1,47 @@
using Ryujinx.Horizon.Ins.Ipc;
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
namespace Ryujinx.Horizon.Ins
{
class InsIpcServer
{
private const int InsMaxSessionsCount = 8;
private const int TotalMaxSessionsCount = InsMaxSessionsCount * 2;
private const int PointerBufferSize = 0x200;
private const int MaxDomains = 0;
private const int MaxDomainObjects = 0;
private const int MaxPortsCount = 2;
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm;
private ServerManager _serverManager;
public void Initialize()
{
HeapAllocator allocator = new();
_sm = new SmApi();
_sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
#pragma warning disable IDE0055 // Disable formatting
_serverManager.RegisterObjectForServer(new ReceiverManager(), ServiceName.Encode("ins:r"), InsMaxSessionsCount); // 9.0.0+
_serverManager.RegisterObjectForServer(new SenderManager(), ServiceName.Encode("ins:s"), InsMaxSessionsCount); // 9.0.0+
#pragma warning restore IDE0055
}
public void ServiceRequests()
{
_serverManager.ServiceRequests();
}
public void Shutdown()
{
_serverManager.Dispose();
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Ryujinx.Horizon.Ins
{
class InsMain : IService
{
public static void Main(ServiceTable serviceTable)
{
InsIpcServer ipcServer = new();
ipcServer.Initialize();
serviceTable.SignalServiceReady();
ipcServer.ServiceRequests();
ipcServer.Shutdown();
}
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Ins;
namespace Ryujinx.Horizon.Ins.Ipc
{
partial class ReceiverManager : IReceiverManager
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Ins;
namespace Ryujinx.Horizon.Ins.Ipc
{
partial class SenderManager : ISenderManager
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Ovln;
namespace Ryujinx.Horizon.Ovln.Ipc
{
partial class ReceiverService : IReceiverService
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Ovln;
namespace Ryujinx.Horizon.Ovln.Ipc
{
partial class SenderService : ISenderService
{
}
}

View File

@@ -0,0 +1,48 @@
using Ryujinx.Horizon.Ovln.Ipc;
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
namespace Ryujinx.Horizon.Ovln
{
class OvlnIpcServer
{
private const int OvlnRcvMaxSessionsCount = 2;
private const int OvlnSndMaxSessionsCount = 20;
private const int TotalMaxSessionsCount = OvlnRcvMaxSessionsCount + OvlnSndMaxSessionsCount;
private const int PointerBufferSize = 0;
private const int MaxDomains = 21;
private const int MaxDomainObjects = 60;
private const int MaxPortsCount = 2;
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm;
private ServerManager _serverManager;
public void Initialize()
{
HeapAllocator allocator = new();
_sm = new SmApi();
_sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
#pragma warning disable IDE0055 // Disable formatting
_serverManager.RegisterObjectForServer(new ReceiverService(), ServiceName.Encode("ovln:rcv"), OvlnRcvMaxSessionsCount); // 8.0.0+
_serverManager.RegisterObjectForServer(new SenderService(), ServiceName.Encode("ovln:snd"), OvlnSndMaxSessionsCount); // 8.0.0+
#pragma warning restore IDE0055
}
public void ServiceRequests()
{
_serverManager.ServiceRequests();
}
public void Shutdown()
{
_serverManager.Dispose();
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Ryujinx.Horizon.Ovln
{
class OvlnMain : IService
{
public static void Main(ServiceTable serviceTable)
{
OvlnIpcServer ipcServer = new();
ipcServer.Initialize();
serviceTable.SignalServiceReady();
ipcServer.ServiceRequests();
ipcServer.Shutdown();
}
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Psc;
namespace Ryujinx.Horizon.Psc.Ipc
{
partial class PmControl : IPmControl
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Psc;
namespace Ryujinx.Horizon.Psc.Ipc
{
partial class PmService : IPmService
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Psc;
namespace Ryujinx.Horizon.Psc.Ipc
{
partial class PmStateLock : IPmStateLock
{
}
}

View File

@@ -0,0 +1,50 @@
using Ryujinx.Horizon.Psc.Ipc;
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
namespace Ryujinx.Horizon.Psc
{
class PscIpcServer
{
private const int PscCMaxSessionsCount = 1;
private const int PscMMaxSessionsCount = 50;
private const int PscLMaxSessionsCount = 5;
private const int TotalMaxSessionsCount = PscCMaxSessionsCount + PscMMaxSessionsCount + PscLMaxSessionsCount;
private const int PointerBufferSize = 0;
private const int MaxDomains = 0;
private const int MaxDomainObjects = 0;
private const int MaxPortsCount = 3;
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm;
private ServerManager _serverManager;
public void Initialize()
{
HeapAllocator allocator = new();
_sm = new SmApi();
_sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
#pragma warning disable IDE0055 // Disable formatting
_serverManager.RegisterObjectForServer(new PmControl(), ServiceName.Encode("psc:c"), PscCMaxSessionsCount);
_serverManager.RegisterObjectForServer(new PmService(), ServiceName.Encode("psc:m"), PscMMaxSessionsCount);
_serverManager.RegisterObjectForServer(new PmStateLock(), ServiceName.Encode("psc:l"), PscLMaxSessionsCount); // 9.0.0+
#pragma warning restore IDE0055
}
public void ServiceRequests()
{
_serverManager.ServiceRequests();
}
public void Shutdown()
{
_serverManager.Dispose();
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Ryujinx.Horizon.Psc
{
class PscMain : IService
{
public static void Main(ServiceTable serviceTable)
{
PscIpcServer ipcServer = new();
ipcServer.Initialize();
serviceTable.SignalServiceReady();
ipcServer.ServiceRequests();
ipcServer.Shutdown();
}
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Hshl
{
interface IManager : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Hshl
{
interface ISetterManager : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Ins
{
interface IReceiverManager : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Ins
{
interface ISenderManager : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Ovln
{
interface IReceiverService : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Ovln
{
interface ISenderService : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Psc
{
interface IPmControl : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Psc
{
interface IPmService : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Psc
{
interface IPmStateLock : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Srepo
{
interface ISrepoService : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IClientRootSession : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IDsRootSession : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IPdCradleManager : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IPdManager : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IPdManufactureManager : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IPmObserverService : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IPmService : IServiceObject
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Usb
{
interface IQdbManager : IServiceObject
{
}
}

View File

@@ -1,9 +1,15 @@
using Ryujinx.Horizon.Bcat; using Ryujinx.Horizon.Bcat;
using Ryujinx.Horizon.Hshl;
using Ryujinx.Horizon.Ins;
using Ryujinx.Horizon.Lbl; using Ryujinx.Horizon.Lbl;
using Ryujinx.Horizon.LogManager; using Ryujinx.Horizon.LogManager;
using Ryujinx.Horizon.MmNv; using Ryujinx.Horizon.MmNv;
using Ryujinx.Horizon.Ngc; using Ryujinx.Horizon.Ngc;
using Ryujinx.Horizon.Ovln;
using Ryujinx.Horizon.Prepo; using Ryujinx.Horizon.Prepo;
using Ryujinx.Horizon.Psc;
using Ryujinx.Horizon.Srepo;
using Ryujinx.Horizon.Usb;
using Ryujinx.Horizon.Wlan; using Ryujinx.Horizon.Wlan;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
@@ -27,12 +33,18 @@ namespace Ryujinx.Horizon
} }
RegisterService<BcatMain>(); RegisterService<BcatMain>();
RegisterService<HshlMain>();
RegisterService<InsMain>();
RegisterService<LblMain>(); RegisterService<LblMain>();
RegisterService<LmMain>(); RegisterService<LmMain>();
RegisterService<MmNvMain>(); RegisterService<MmNvMain>();
RegisterService<PrepoMain>();
RegisterService<WlanMain>();
RegisterService<NgcMain>(); RegisterService<NgcMain>();
RegisterService<OvlnMain>();
RegisterService<PrepoMain>();
RegisterService<PscMain>();
RegisterService<SrepoMain>();
RegisterService<UsbMain>();
RegisterService<WlanMain>();
_totalServices = entries.Count; _totalServices = entries.Count;

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Srepo;
namespace Ryujinx.Horizon.Srepo.Ipc
{
partial class SrepoService : ISrepoService
{
}
}

View File

@@ -0,0 +1,46 @@
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
using Ryujinx.Horizon.Srepo.Ipc;
namespace Ryujinx.Horizon.Srepo
{
class SrepoIpcServer
{
private const int SrepoAMaxSessionsCount = 2;
private const int SrepoUMaxSessionsCount = 30;
private const int TotalMaxSessionsCount = SrepoAMaxSessionsCount + SrepoUMaxSessionsCount;
private const int PointerBufferSize = 0x80;
private const int MaxDomains = 32;
private const int MaxDomainObjects = 192;
private const int MaxPortsCount = 2;
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm;
private ServerManager _serverManager;
public void Initialize()
{
HeapAllocator allocator = new();
_sm = new SmApi();
_sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
_serverManager.RegisterObjectForServer(new SrepoService(), ServiceName.Encode("srepo:a"), SrepoAMaxSessionsCount); // 5.0.0+
_serverManager.RegisterObjectForServer(new SrepoService(), ServiceName.Encode("srepo:u"), SrepoUMaxSessionsCount); // 5.0.0+
}
public void ServiceRequests()
{
_serverManager.ServiceRequests();
}
public void Shutdown()
{
_serverManager.Dispose();
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Ryujinx.Horizon.Srepo
{
class SrepoMain : IService
{
public static void Main(ServiceTable serviceTable)
{
SrepoIpcServer ipcServer = new();
ipcServer.Initialize();
serviceTable.SignalServiceReady();
ipcServer.ServiceRequests();
ipcServer.Shutdown();
}
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class ClientRootSession : IClientRootSession
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class DsRootSession : IDsRootSession
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class PdCradleManager : IPdCradleManager
{
}
}

View File

@@ -0,0 +1,9 @@
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class PdManager : IPdManager
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class PdManufactureManager : IPdManufactureManager
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class PmObserverService : IPmObserverService
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class PmService : IPmService
{
}
}

View File

@@ -0,0 +1,8 @@
using Ryujinx.Horizon.Sdk.Usb;
namespace Ryujinx.Horizon.Usb.Ipc
{
partial class QdbManager : IQdbManager
{
}
}

View File

@@ -0,0 +1,71 @@
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
using Ryujinx.Horizon.Usb.Ipc;
namespace Ryujinx.Horizon.Usb
{
class UsbIpcServer
{
private const int UsbDsMaxSessionsCount = 4;
private const int UsbHsMaxSessionsCount = 20;
private const int UsbHsAMaxSessionsCount = 3;
private const int UsbObsvMaxSessionsCount = 2;
private const int UsbPdMaxSessionsCount = 6;
private const int UsbPdCMaxSessionsCount = 4;
private const int UsbPdMMaxSessionsCount = 1;
private const int UsbPmMaxSessionsCount = 5;
private const int UsbQdbMaxSessionsCount = 4;
private const int TotalMaxSessionsCount =
UsbDsMaxSessionsCount +
UsbHsMaxSessionsCount +
UsbHsAMaxSessionsCount +
UsbObsvMaxSessionsCount +
UsbPdMaxSessionsCount +
UsbPdCMaxSessionsCount +
UsbPdMMaxSessionsCount +
UsbPmMaxSessionsCount +
UsbQdbMaxSessionsCount;
private const int PointerBufferSize = 0;
private const int MaxDomains = 0;
private const int MaxDomainObjects = 0;
private const int MaxPortsCount = 9;
private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm;
private ServerManager _serverManager;
public void Initialize()
{
HeapAllocator allocator = new();
_sm = new SmApi();
_sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, TotalMaxSessionsCount);
#pragma warning disable IDE0055 // Disable formatting
_serverManager.RegisterObjectForServer(new DsRootSession(), ServiceName.Encode("usb:ds"), UsbDsMaxSessionsCount);
_serverManager.RegisterObjectForServer(new ClientRootSession(), ServiceName.Encode("usb:hs"), UsbHsMaxSessionsCount);
_serverManager.RegisterObjectForServer(new ClientRootSession(), ServiceName.Encode("usb:hs:a"), UsbHsAMaxSessionsCount); // 7.0.0+
_serverManager.RegisterObjectForServer(new PmObserverService(), ServiceName.Encode("usb:obsv"), UsbObsvMaxSessionsCount); // 8.0.0+
_serverManager.RegisterObjectForServer(new PdManager(), ServiceName.Encode("usb:pd"), UsbPdMaxSessionsCount);
_serverManager.RegisterObjectForServer(new PdCradleManager(), ServiceName.Encode("usb:pd:c"), UsbPdCMaxSessionsCount);
_serverManager.RegisterObjectForServer(new PdManufactureManager(), ServiceName.Encode("usb:pd:m"), UsbPdMMaxSessionsCount); // 1.0.0
_serverManager.RegisterObjectForServer(new PmService(), ServiceName.Encode("usb:pm"), UsbPmMaxSessionsCount);
_serverManager.RegisterObjectForServer(new QdbManager(), ServiceName.Encode("usb:qdb"), UsbQdbMaxSessionsCount); // 7.0.0+
#pragma warning restore IDE0055
}
public void ServiceRequests()
{
_serverManager.ServiceRequests();
}
public void Shutdown()
{
_serverManager.Dispose();
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Ryujinx.Horizon.Usb
{
class UsbMain : IService
{
public static void Main(ServiceTable serviceTable)
{
UsbIpcServer ipcServer = new();
ipcServer.Initialize();
serviceTable.SignalServiceReady();
ipcServer.ServiceRequests();
ipcServer.Shutdown();
}
}
}